Я хочу сохранить результат этой функции curl в переменной, как я могу это сделать?
#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;
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;
}
CURLcode res;
не используетсяОтветы:
Вы можете установить функцию обратного вызова для приема входящих блоков данных, используя
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; }
источник
size_t
(кроме негоlen
самого) были заявленыconst
.std::string
перейдите сюдаСледующий ответ - это способ сделать это в 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; try { s->append((char*)contents, newLength); } catch(std::bad_alloc &e) { //handle memory problem return 0; } return newLength; } 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; }
источник
s->append((char*)contents. nmemb);
у меня работает безупречно и более лаконично. Кроме того, официальная сигнатура функции для обратного вызова имеетchar*
первый аргумент, поэтому вы можете использовать его и опустить приведение. И, наконец,s->resize()
фактически инициализирует вновь выделенное пространство. Так как вы все равно собираетесь его перезаписать,s->reserve()
было бы более эффективно.Из прочтения руководства здесь: http://curl.haxx.se/libcurl/c/curl_easy_setopt.html Я думаю, вам нужно несколько вызовов CURL_SETOPT, первый - это URL-адрес, который вы хотите обработать, а второй - что-то вроде:
Где function_ptr соответствует этой подписи:
size_t function( void *ptr, size_t size, size_t nmemb, void *stream)
Здесь вы указываете функцию обратного вызова, которую libcurl будет вызывать, когда у нее есть какие-то выходные данные для записи из любой вызванной вами передачи. Вы можете заставить его автоматически писать в файл или передать ему указатель на функцию, которая сама будет обрабатывать вывод. Используя эту функцию, вы сможете собрать различные выходные строки в одну часть, а затем использовать их в своей программе.
Я не уверен, какие другие параметры вам, возможно, придется установить / что еще влияет на то, как вы хотите, чтобы ваше приложение вело себя, поэтому внимательно просмотрите эту страницу.
источник
Вот вариант принятого ответа от alex-jasmin на С ++
#include <iostream> #include <string> #include <curl/curl.h> size_t writefunc(void *ptr, size_t size, size_t nmemb, std::string *s) { s->append(static_cast<char *>(ptr), size*nmemb); return size*nmemb; } int main(void) { CURL *curl = curl_easy_init(); if (curl) { std::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); CURLcode res = curl_easy_perform(curl); std::cout << s << std::endl; /* always cleanup */ curl_easy_cleanup(curl); } return 0; }
источник