Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

最近無性に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についてまとめるはず

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

参考

https://curl.haxx.se/libcurl/c/

komi9977
最終目標はフルスタックエンジニア
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away