【问题标题】:libcurl problem with getting data from curl_easy_perform()从 curl_easy_perform() 获取数据的 libcurl 问题
【发布时间】:2011-06-12 17:08:31
【问题描述】:

这可能是一个愚蠢的问题,但我实际上如何获取 curl_easy_perform() 返回的站点数据到我可以使用的变量中。当它执行时,我只是看到它在终端上一闪而过。顺便说一句,我正在使用 C。

有什么想法吗?谢谢。

编辑: 这是我正在使用的代码(我正在访问 Twitter Streaming API,我做得对吗?)

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

  curl = curl_easy_init();
  if(curl) {
    curl_easy_setopt(curl, CURLOPT_URL, "http://stream.twitter.com/1/statuses/filter.json?track=http");
curl_easy_setopt(curl, CURLOPT_USERPWD, "JEggers2:password");
    res = curl_easy_perform(curl);

    /* always cleanup */ 
    curl_easy_cleanup(curl);


  }   
  return 0;
}

【问题讨论】:

    标签: c curl libcurl


    【解决方案1】:

    要将数据转换成字符串,需要设置写回调函数:

    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback_func);
    

    另外,接收数据的字符串变量的地址:

    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &str)
    

    回调函数如下所示:

    size_t callback_func(void *ptr, size_t size, size_t count, void *stream)
    {
          /* ptr - your string variable.
          stream - data chuck you received */
    
         printf("%.*s", size, (char*)stream);
    }
    

    因为您不知道要接收的数据的总大小,所以您需要重新分配指针以将其放入字符串中。

    【讨论】:

    • 你能给我一个回调函数的例子吗?谢谢
    • 我得到:main.c:10:警告:格式不是字符串文字,也没有格式参数。有什么想法吗?
    • 我猜你需要printf("%s", (char*)stream);
    • 感谢戴夫,它有效 :) 如果您从上一个示例中删除多余的左括号,我将继续将其标记为答案!
    • NOOOOOOOOOOO 传递给回调的数据不是以零结尾的。你不能也不能像 printf %s 这样对它进行字符串操作。请参阅此示例 curl.haxx.se/libcurl/c/getinmemory.html
    【解决方案2】:

    另一个答案在使用callback_func 的第一个和最后一个参数时似乎是错误的(请参阅the docs)。您收到的实际数据块在第一个参数ptr 中,而您使用CURLOPT_WRITEDATA 传递的指针是最后一个参数。

    我已经做了一个完整的可编译示例:

    #include <stdlib.h>
    #include <string.h>
    #include <curl/curl.h>
    
    size_t dataSize=0;
    size_t curlWriteFunction(void* ptr, size_t size/*always==1*/,
                             size_t nmemb, void* userdata)
    {
        char** stringToWrite=(char**)userdata;
        const char* input=(const char*)ptr;
        if(nmemb==0) return 0;
        if(!*stringToWrite)
            *stringToWrite=malloc(nmemb+1);
        else
            *stringToWrite=realloc(*stringToWrite, dataSize+nmemb+1);
        memcpy(*stringToWrite+dataSize, input, nmemb);
        dataSize+=nmemb;
        (*stringToWrite)[dataSize]='\0';
        return nmemb;
    }
    
    int main()
    {
        char* data=0;
        CURL*const curl=curl_easy_init();
        if(!curl)
        {
            fprintf(stderr, "Failed to init curl");
            return 1;
        }
        curl_easy_setopt(curl, CURLOPT_URL, "https://www.google.com");
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &data);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &curlWriteFunction);
        if(curl_easy_perform(curl)!=CURLE_OK)
        {
            fprintf(stderr, "Failed to get web page\n");
            return 1;
        }
        curl_easy_cleanup(curl);
    
        if(!data)
        {
            fprintf(stderr, "Got no data\n");
            return 1;
        }
    
        printf("Page data:\n\n%s\n", data);
        free(data);
    }
    

    【讨论】:

    • 这对我帮助很大,但由于某种原因,当我运行它(在 c++ 中)时,这个案例从未被调用:if(!*stringToWrite) *stringToWrite=malloc(nmemb+1))。我不得不在第一次使用if(dataSize==0) 强制它进入这个条件。在这样做之前,如果在第一次调用 malloc 之前尝试重新分配,由于某种原因会出现段错误。
    【解决方案3】:

    函数 writeDataOnStream 有一个称为缓冲区的空指针,该指针保存所有数据(HTML 代码和标题)

    #include <iostream>
    #include <string.h>
    #include <curl/curl.h>
    
    using namespace std;
    
    //ADD THIS FUNCTION: NOTE the Void pointer "buffer"
    size_t writeDataOnStream(void * buffer, size_t size, size_t nbytes, void * stream){
        size_t bytes_written = fwrite( buffer, size, nbytes, (FILE *) stream);
        return bytes_written;
    }
    
    int main(void)
    {
      CURL *curl;
      CURLcode res;
    
      curl = curl_easy_init();
      if(curl) {
         curl_easy_setopt(curl, CURLOPT_URL, "http://stream.twitter.com/1/statuses/filter.json?track=http");
         curl_easy_setopt(curl, CURLOPT_USERPWD, "JEggers2:password");
    
         //APPEND THIS
         curl_easy_setopt(curl, CURLOPT_HEADER, 1L);  //Enable Headers
         curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeDataOnStream);
         curl_easy_setopt(curl, CURLOPT_WRITEDATA, stdout);   //Print data in STDOUT
         //END
    
         res = curl_easy_perform(curl);
         curl_easy_cleanup(curl);      // always cleanup
      }   
      return 0;
    }
    

    CURLOPT_WRITEFUNCTION

    CURLOPT_WRITEDATA

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-08-17
      • 2023-03-17
      • 1970-01-01
      • 2021-09-26
      • 2014-12-23
      • 2011-11-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多