LoginSignup
2
0

More than 5 years have passed since last update.

c++の基本を備忘録的にまとめていく Part3 (libcurl)

Last updated at Posted at 2019-02-16

最近無性にc++をやりたい

やったこと

libcurlをインストール & mnistをダウンロードした。

とりあえず機械学習のド定番mnistによる文字認識をやろうと思い、mnistをダウンロードしようと思った。

以下コマンドs

brew install curl

これで

#include <curl/curl.h>

でインクルードできるはずだと思ったが、問題が

error
Undefined symbols for architecture x86_64:
  "_curl_easy_cleanup", referenced from:
      _main in libcurl-e55a4c.o
  "_curl_easy_init", referenced from:
      _main in libcurl-e55a4c.o
  "_curl_easy_perform", referenced from:
      _main in libcurl-e55a4c.o
  "_curl_easy_setopt", referenced from:
      _main in libcurl-e55a4c.o
ld: symbol(s) not found for architecture x86_64

みたいなエラーメッセージが、
pathとか確認したり、色々やった果てに
同じエラーをstack overflowにて発見,
コンパイルする時-lcurlオプションをつければ良いらしい

g++ test.cpp -lcurl

コマンドだとこんな感じでコンパイル出来た。

そして以下がダウンロード用のプログラム

download_mnist.cpp
#include <stdlib.h>
#include <curl/curl.h>
#include <iostream>
#include <string>

void download_mnist() {
  FILE *fp;
  std::string read_filenames[4] = {
    "train-images-idx3-ubyte.gz",
    "train-labels-idx1-ubyte.gz",
    "t10k-images-idx3-ubyte.gz",
    "t10k-labels-idx1-ubyte.gz"
  };

  std::string out_dir = "./datasets/mnist";
  std::string out_filenames[4] = {
    "train_images",
    "train_labels",
    "test_images",
    "test_labels"
  };

  CURLcode res;
  std::string url, out;
  for (unsigned i = 0; i < 4; i++) {
    curl = curl_easy_init();
    url = "http://yann.lecun.com/exdb/mnist/" + read_filenames[i];
    out = out_dir + "/" + out_filenames[i] + ".gz";

    if ( (fp=fopen(out.c_str(), "wb")) == NULL ) {
      std::cout << "can't open file" << std::endl;
      std::exit(EXIT_FAILURE);
    } else {
      std::cout << "downloading "<< out_filenames[i] << "..." << std::endl;
      curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
      curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NULL);
      curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
      res = curl_easy_perform(curl);
      if (res != CURLE_OK) {
        std::cout << "curl_easy_perform() failed: " << curl_easy_strerror(res) << std::endl;
        std::exit(EXIT_FAILURE);
      }
      curl_easy_cleanup(curl);
     }
    fclose(fp);
    std::cout << "downloaded " << out_filenames[i] << "." std::endl;
  }
}

簡単にまとめると
curl_easy_init(): curlポインタの初期化, このcurlに色々な情報が格納されている?
curl_easy_setopt: ダウンロードするurlとか、関数とか、出力先を設定する
curl_easy_perform: curlのレスポンスを取得
curl_easy_cleanup: curlポインタの解放
みたいな感じだと思われる。

感想

curlはコマンドで打つべし
また、libcurlはc++の基本ではないのでは?という疑問が拭えない

次回こそはclassについてまとめるはず

こんなコードあるよとか、こここうした方がいいのでは?><というコメントとても大切で嬉しいです

参考

2
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0