2010-02-24 91 views
64

我想将这个curl函数的结果存储在一个变量中,我该怎么做?C libcurl获取输出到一个字符串

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

int main(void) 
{ 
    CURL *curl; 
    CURLcode res; 

    curl = curl_easy_init(); 
    if(curl) { 
    curl_easy_setopt(curl, CURLOPT_URL, "curl.haxx.se"); 
    res = curl_easy_perform(curl); 

    /* always cleanup */ 
    curl_easy_cleanup(curl); 
    } 
    return 0; 
} 

谢谢,我解决了这个问题是这样的:

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

function_pt(void *ptr, size_t size, size_t nmemb, void *stream){ 
    printf("%d", atoi(ptr)); 
} 

int main(void) 
{ 
    CURL *curl; 
    CURLcode res; 
    curl = curl_easy_init(); 
    if(curl) { 
    curl_easy_setopt(curl, CURLOPT_URL, "curl.haxx.se"); 
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, function_pt); 
    curl_easy_perform(curl); 
    curl_easy_cleanup(curl); 
    } 
    system("pause"); 
    return 0; 
} 
+1

只是为了在function_pt您的解决方案()要转换的字符串中PTR到整数,以便将其转换回字符串输出指出。您可以直接输出字符串(并查看完整的响应)。 – zzz 2015-06-19 03:33:35

+0

这里是cURL示例的链接http://curl.haxx.se/libcurl/c/getinmemory.html – lafferc 2015-07-30 16:19:47

+0

'CURLcode res;'未使用 – fnc12 2016-09-17 11:14:13

回答

82

你可以设置一个回调函数使用curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, myfunc);

回调将带您可以使用curl_easy_setopt(curl, CURLOPT_WRITEDATA, p)

这里的代码片段经过一个缓冲struct string {*ptr; len}设置一个用户定义的参数来接收传入的数据块回调函数并使用realloc()在每次调用时增加该缓冲区。

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

struct string { 
    char *ptr; 
    size_t len; 
}; 

void init_string(struct string *s) { 
    s->len = 0; 
    s->ptr = malloc(s->len+1); 
    if (s->ptr == NULL) { 
    fprintf(stderr, "malloc() failed\n"); 
    exit(EXIT_FAILURE); 
    } 
    s->ptr[0] = '\0'; 
} 

size_t writefunc(void *ptr, size_t size, size_t nmemb, struct string *s) 
{ 
    size_t new_len = s->len + size*nmemb; 
    s->ptr = realloc(s->ptr, new_len+1); 
    if (s->ptr == NULL) { 
    fprintf(stderr, "realloc() failed\n"); 
    exit(EXIT_FAILURE); 
    } 
    memcpy(s->ptr+s->len, ptr, size*nmemb); 
    s->ptr[new_len] = '\0'; 
    s->len = new_len; 

    return size*nmemb; 
} 

int main(void) 
{ 
    CURL *curl; 
    CURLcode res; 

    curl = curl_easy_init(); 
    if(curl) { 
    struct string s; 
    init_string(&s); 

    curl_easy_setopt(curl, CURLOPT_URL, "curl.haxx.se"); 
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc); 
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s); 
    res = curl_easy_perform(curl); 

    printf("%s\n", s.ptr); 
    free(s.ptr); 

    /* always cleanup */ 
    curl_easy_cleanup(curl); 
    } 
    return 0; 
} 
+0

非常好的答案。我把所有的东西都放在了字符串中。 Yipee! – 2014-01-21 12:21:42

+1

不错。如果所有'size_t'(除了'len'本身)都被声明为'const',更好。 – alk 2014-06-08 18:31:42

7

从这里阅读手册:http://curl.haxx.se/libcurl/c/curl_easy_setopt.html我想你需要多次打电话给CURL_SETOPT,首先是要处理的URL,第二是这样的:

curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, function_ptr); 

凡function_ptr这个签名匹配:

size_t function(void *ptr, size_t size, size_t nmemb, void *stream) 

这里发生了什么是你表示一个回调函数,当它有一些输出写入你调用的任何传输时,libcurl会调用它。你可以让它自动写入一个文件,或者将它传递给一个处理输出本身的函数的指针。使用这个函数,你应该能够把各种输出字符串组合成一块,然后在你的程序中使用它们。

我不确定还有哪些其他选项可能需要设置/还有哪些会影响您的应用的行为方式,因此请仔细阅读该页面。

21

以下的答案是C++的方式来做到这一点,与std::string,而不是空结尾的字符串。它仍然使用回调函数(它没有办法),但也使用try/catch处理分配错误。

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

size_t CurlWrite_CallbackFunc_StdString(void *contents, size_t size, size_t nmemb, std::string *s) 
{ 
    size_t newLength = size*nmemb; 
    size_t oldLength = s->size(); 
    try 
    { 
     s->resize(oldLength + newLength); 
    } 
    catch(std::bad_alloc &e) 
    { 
     //handle memory problem 
     return 0; 
    } 

    std::copy((char*)contents,(char*)contents+newLength,s->begin()+oldLength); 
    return size*nmemb; 
} 
int main() 
{ 
    CURL *curl; 
    CURLcode res; 

    curl_global_init(CURL_GLOBAL_DEFAULT); 

    curl = curl_easy_init(); 
    std::string s; 
    if(curl) 
    { 

     curl_easy_setopt(curl, CURLOPT_URL, "curl.haxx.se"); 

     curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); //only for https 
     curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); //only for https 
     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWrite_CallbackFunc_StdString); 
     curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s); 
     curl_easy_setopt (curl, CURLOPT_VERBOSE, 1L); //remove this to disable verbose output 


     /* Perform the request, res will get the return code */ 
     res = curl_easy_perform(curl); 
     /* Check for errors */ 
     if(res != CURLE_OK) 
     { 
      fprintf(stderr, "curl_easy_perform() failed: %s\n", 
        curl_easy_strerror(res)); 
     } 

     /* always cleanup */ 
     curl_easy_cleanup(curl); 
    } 

    std::cout<<s<<std::endl; 

    std::cout<< "Program finished!" << std::endl; 
} 
+1

为我工作得很好。比上面的答案容易和短... !!! – mbaros 2016-09-23 11:22:46