2012-12-16 8 views
10

私は2つのHTTPレスポンスを比較するために何とかしなければならない宿題があります。私はC言語で書いています。私はlibcurlを使って簡単にします。私は、libcurlを使用して別の関数からHTTPリクエストとレスポンスを呼び出す関数を呼び出しており、HTTPレスポンスをchar *として返したいとします。ここに私のコードは、(それがクラッシュした)これまでです:Cでは、libcurlを使用してHTTPレスポンスを文字列に読み込む方法はありますか?

#include <stdio.h> 
#include <curl/curl.h> 
#include <string.h> 

size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream) { 
    size_t written; 
    written = fwrite(ptr, size, nmemb, stream); 
    return written; 
} 

char *handle_url(void) { 
    CURL *curl; 
    char *fp; 
    CURLcode res; 
    char *url = "http://www.yahoo.com"; 
    curl = curl_easy_init(); 
    if (curl) { 
     curl_easy_setopt(curl, CURLOPT_URL, url); 
     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data); 
     curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); 
     res = curl_easy_perform(curl); 
     if(res != CURLE_OK) 
       fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); 

     curl_easy_cleanup(curl); 

     //printf("\n%s", fp); 
    } 
    return fp; 
} 

私はちょうど呼び出し元の関数に文字列を返すようにしたいので、私の場合には動作しますが、ないC libcurl get output into a stringこのソリューションは。

アイデア?

+0

'char * fp;'とは何ですか?なぜあなたはそれを返すのですか?どのように/あなたはそれのためのメモリを割り当てていますか?私の眼鏡はどこですか? –

+0

。私はCを書く年を持っていたので、私はゼロに戻っています。それは、 "C libcurlの文字列への出力を取得する"で動作していることです。上記の例を参考にしています。私は正確なデータ入力がわからないので、char * fpのためにメモリを割り当てるのがうまくいくかどうかわかりません。 –

+0

あなたの 'write_data'は' char * fp'をパラメータとして渡すべきですが、 'FILE'を取るように定義しました。また、 'write_func'が複数回呼び出されるケースを処理する必要があるでしょう。最後に、期待通りに動作させたい場合、 'char * fp'はポインタへのポインタとして' write_func() 'に渡されなければならないので、適切に割り当てることができます。言い換えれば、 'write_func()'は 'FILE * 'ではなく' char ** 'を取るべきです。 – mpontillo

答えて

18

あなたのために修正されました。 write_data()関数が複数回呼び出された場合を処理し、正しい種類のパラメータを渡す必要があります。あなたはまた、あなたが持っている構造の大きさを追跡する必要があるので、十分なメモリを割り当てることができます。

printfwrite_data機能でデバッグを行いましたが、その動作を理解するのに役立ちます。

#include <stdio.h> 
#include <curl/curl.h> 
#include <string.h> 
#include <stdlib.h> 

struct url_data { 
    size_t size; 
    char* data; 
}; 

size_t write_data(void *ptr, size_t size, size_t nmemb, struct url_data *data) { 
    size_t index = data->size; 
    size_t n = (size * nmemb); 
    char* tmp; 

    data->size += (size * nmemb); 

#ifdef DEBUG 
    fprintf(stderr, "data at %p size=%ld nmemb=%ld\n", ptr, size, nmemb); 
#endif 
    tmp = realloc(data->data, data->size + 1); /* +1 for '\0' */ 

    if(tmp) { 
     data->data = tmp; 
    } else { 
     if(data->data) { 
      free(data->data); 
     } 
     fprintf(stderr, "Failed to allocate memory.\n"); 
     return 0; 
    } 

    memcpy((data->data + index), ptr, n); 
    data->data[data->size] = '\0'; 

    return size * nmemb; 
} 

char *handle_url(char* url) { 
    CURL *curl; 

    struct url_data data; 
    data.size = 0; 
    data.data = malloc(4096); /* reasonable size initial buffer */ 
    if(NULL == data.data) { 
     fprintf(stderr, "Failed to allocate memory.\n"); 
     return NULL; 
    } 

    data.data[0] = '\0'; 

    CURLcode res; 

    curl = curl_easy_init(); 
    if (curl) { 
     curl_easy_setopt(curl, CURLOPT_URL, url); 
     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data); 
     curl_easy_setopt(curl, CURLOPT_WRITEDATA, &data); 
     res = curl_easy_perform(curl); 
     if(res != CURLE_OK) { 
       fprintf(stderr, "curl_easy_perform() failed: %s\n", 
         curl_easy_strerror(res)); 
     } 

     curl_easy_cleanup(curl); 

    } 
    return data.data; 
} 

int main(int argc, char* argv[]) { 
    char* data; 

    if(argc < 2) { 
     fprintf(stderr, "Must provide URL to fetch.\n"); 
     return 1; 
    } 
    data = handle_url(argv[1]); 

    if(data) { 
     printf("%s\n", data); 
     free(data); 
    } 

    return 0; 
} 

注:​​(あなたがtest.cに貼り付けると仮定)でコンパイルします。 呼び出しを参照するには、gcc -o test test.c -lcurl -DDEBUGを使用してください。

免責事項:これは醜い、クイックアンドダーティーなコードです。バグがあるかもしれません。 more robust, better commented example hereをご覧ください。

+0

ありがとう@マイク、それは動作します!今は、allocとmallocがどのように動作するかを覚えておくだけです。 –

+1

おめでとう、あなたはgetinmemory.c libcurlの例を再実装しました:http://curl.haxx.se/libcurl/c/getinmemory.html :-) –

+1

@ダニエル、おはよう、ありがとう。とにかく理解するのは楽しい演習でした。 =) – mpontillo

関連する問題