每当打印 CURL_WRITEFUNCTION 中的 ptr 时都会输出奇怪的字符。

发布于 2024-10-13 11:26:05 字数 861 浏览 4 评论 0原文

我遇到了一些问题,这是我的代码(我使用的是 C):

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

size_t callback_func(void *ptr, size_t size, size_t count, void *stream) {
//json_object *json_obj = json_tokener_parse(ptr);
printf ("%s",(char*)ptr);

return count;

}

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, "Firrus:password");
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback_func);
    curl_easy_perform(curl);



    /* always cleanup */ 
    curl_easy_cleanup(curl);


  }

  return 0;
}

问题是,每次打印 ptr 时,顶部也会输出三个奇怪的(看似随机的)字符,例如 77D 或6DA。这些字符是什么意思?我怎样才能删除它们?

I'm having a bit of an issue, here is my code (I'm using C):

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

size_t callback_func(void *ptr, size_t size, size_t count, void *stream) {
//json_object *json_obj = json_tokener_parse(ptr);
printf ("%s",(char*)ptr);

return count;

}

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, "Firrus:password");
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback_func);
    curl_easy_perform(curl);



    /* always cleanup */ 
    curl_easy_cleanup(curl);


  }

  return 0;
}

The problem is that, every time ptr is printed, three weird (seemingly random) characters are also outputted at the top, e.g. 77D or 6DA. What do these characters mean? How can I remove them?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

皓月长歌 2024-10-20 11:26:05

根据文档,回调函数的工作方式如下:

应该匹配的函数指针
以下原型: size_t 函数(
void *ptr, size_t 大小, size_t nmemb,
无效*用户数据);这个函数得到
一旦有就由 libcurl 调用
收到的需要保存的数据。
ptr指向的数据大小
大小乘以 nmemb,它将
不以零结尾
。返回
实际处理的字节数
的。如果该金额与
传递给你的函数的金额,它会
向库发出错误信号。这
将中止传输并返回
CURLE_WRITE_ERROR。
从7.18.0开始,该函数可以返回
CURL_WRITEFUNC_PAUSE 然后将
导致写入此连接
变得暂停。参见curl_easy_pause(3)
了解更多详情。

该函数可以用零调用
如果传输的文件是字节数据
空。

......

使用以下命令设置用户数据参数
CURLOPT_WRITEDATA 选项。

回调函数将被传递
尽可能多的数据
调用,但你不可能使
任何假设。可能是一个字节,
可能有数千个。最大
可以传递的数据量
写回调定义在
卷曲.h头文件:
CURL_MAX_WRITE_SIZE。

因此您的回调可能会被调用多次。
您需要将数据存储到您自己的结构中,该结构将跟踪迄今为止读取的数据。

尝试这个解决方案:

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

typedef struct {
    size_t size;
    char *payload;
}srvresponse;

size_t callback_func(void *ptr, size_t size, size_t count, void *stream) {
    //printf("%s", (char*) ptr);

    size_t realsize = size * count;
    printf("Chuncksize:%lu\n",realsize);
    srvresponse *ret = (srvresponse*)stream;
    //Increase the payload size
    ret->payload = realloc(ret->payload,ret->size + realsize + 1);
    //Copy the new data
    memcpy(&(ret->payload[ret->size]),ptr,realsize);
    //Update the size
    ret->size += realsize;
    //Terminate the string
    ret->payload[ret->size] = 0;
    printf("Read so far:%s",ret->payload);
    return realsize;

}

int main(void) {
    CURL *curl;

    srvresponse retdata;
    retdata.payload = malloc(1);//We increase the capacity later
    retdata.size = 0;

    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, "user:pass");
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback_func);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&retdata);
        curl_easy_perform(curl);
        curl_easy_cleanup(curl);
        curl_global_cleanup();


        if (retdata.payload){
            puts(retdata.payload);
            free(retdata.payload);
        }
    }

    return 0;
}

In according with the documentation the callback functions works on this way:

Function pointer that should match the
following prototype: size_t function(
void *ptr, size_t size, size_t nmemb,
void *userdata); This function gets
called by libcurl as soon as there is
data received that needs to be saved.
The size of the data pointed to by ptr
is size multiplied with nmemb, it will
not be zero terminated
. Return the
number of bytes actually taken care
of. If that amount differs from the
amount passed to your function, it'll
signal an error to the library. This
will abort the transfer and return
CURLE_WRITE_ERROR.
From 7.18.0, the function can return
CURL_WRITEFUNC_PAUSE which then will
cause writing to this connection to
become paused. See curl_easy_pause(3)
for further details.

This function may be called with zero
bytes data if the transferred file is
empty.

.....

Set the userdata argument with the
CURLOPT_WRITEDATA option.

The callback function will be passed
as much data as possible in all
invokes, but you cannot possibly make
any assumptions. It may be one byte,
it may be thousands. The maximum
amount of data that can be passed to
the write callback is defined in the
curl.h header file:
CURL_MAX_WRITE_SIZE.

So your callback could be called many times.
You need to store the data into your own structure which will keep track about the data read so far.

Try this solution:

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

typedef struct {
    size_t size;
    char *payload;
}srvresponse;

size_t callback_func(void *ptr, size_t size, size_t count, void *stream) {
    //printf("%s", (char*) ptr);

    size_t realsize = size * count;
    printf("Chuncksize:%lu\n",realsize);
    srvresponse *ret = (srvresponse*)stream;
    //Increase the payload size
    ret->payload = realloc(ret->payload,ret->size + realsize + 1);
    //Copy the new data
    memcpy(&(ret->payload[ret->size]),ptr,realsize);
    //Update the size
    ret->size += realsize;
    //Terminate the string
    ret->payload[ret->size] = 0;
    printf("Read so far:%s",ret->payload);
    return realsize;

}

int main(void) {
    CURL *curl;

    srvresponse retdata;
    retdata.payload = malloc(1);//We increase the capacity later
    retdata.size = 0;

    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, "user:pass");
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback_func);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&retdata);
        curl_easy_perform(curl);
        curl_easy_cleanup(curl);
        curl_global_cleanup();


        if (retdata.payload){
            puts(retdata.payload);
            free(retdata.payload);
        }
    }

    return 0;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文