Странные символы выводятся всякий раз, когда выводится ptr из CURL_WRITEFUNCTION. - PullRequest
3 голосов
/ 21 января 2011

У меня небольшая проблема, вот мой код (я использую 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. Что означают эти персонажи? Как я могу удалить их?

1 Ответ

3 голосов
/ 22 января 2011

В соответствии с документацией функции обратного вызова работают следующим образом:

Указатель функции, который должен соответствовать следующему прототипу: функция size_t (void * ptr, size_t size, size_t nmemb, void * userdata);Эта функция вызывается libcurl, как только получаются данные, которые необходимо сохранить. Размер данных, на которые указывает ptr, равен размеру, умноженному на nmemb, он не будет завершаться нулями .Возвращает количество байтов, фактически обработанных.Если эта сумма отличается от суммы, переданной в вашу функцию, она сообщит об ошибке в библиотеку.Это прервет передачу и вернет CURLE_WRITE_ERROR.Начиная с версии 7.18.0, функция может возвращать CURL_WRITEFUNC_PAUSE, что приведет к приостановке записи в это соединение.Подробности см. В curl_easy_pause (3).

Эта функция может вызываться с нулевыми байтами данных, если переданный файл пуст.

.....

УстановитьАргумент userdata с параметром CURLOPT_WRITEDATA.

Функция обратного вызова будет передавать как можно больше данных во всех вызовах, но вы не можете делать какие-либо предположения.Это может быть один байт, это может быть тысячи.Максимальный объем данных, который может быть передан обратному вызову записи, определен в заголовочном файле curl.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;
}
...