Chcę zapisać wynik tej funkcji curl w zmiennej, jak mogę to zrobić?
#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;
}
dzięki, rozwiązałem to tak:
#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;
jest nieużywanyOdpowiedzi:
Możesz ustawić funkcję wywołania zwrotnego, aby odbierać przychodzące fragmenty danych za pomocą
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, myfunc);
Wywołanie zwrotne przyjmie argument zdefiniowany przez użytkownika, który można ustawić za pomocą
curl_easy_setopt(curl, CURLOPT_WRITEDATA, p)
Oto fragment kodu, który przekazuje bufor
struct string {*ptr; len}
do funkcji zwrotnej i powiększa ten bufor przy każdym wywołaniu za pomocą funkcji 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; }
źródło
size_t
(opróczlen
siebie) zostały zadeklarowaneconst
.std::string
przejdź tutajNastępująca odpowiedź to sposób C ++, aby to zrobić
std::string
, zamiast łańcucha zakończonego znakiem null. Nadal używa funkcji zwrotnej (nie da się jej obejść), ale także obsługuje błąd alokacji za pomocą 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; }
źródło
s->append((char*)contents. nmemb);
działa ze mną bezbłędnie i jest bardziej zwięzły. Ponadto oficjalna sygnatura funkcji wywołania zwrotnego machar*
jako pierwszy argument, więc możesz go użyć i pominąć rzutowanie. I wreszcie,s->resize()
faktycznie inicjalizuje nowo przydzielone miejsce. Ponieważ i tak masz zamiar go nadpisać,s->reserve()
byłoby bardziej wydajne.Czytając instrukcję tutaj: http://curl.haxx.se/libcurl/c/curl_easy_setopt.html Myślę, że potrzebujesz kilku wywołań CURL_SETOPT, pierwszy to adres URL, który chcesz przetworzyć, a drugi to coś w rodzaju:
Gdzie function_ptr pasuje do tego podpisu:
size_t function( void *ptr, size_t size, size_t nmemb, void *stream)
To, co się tutaj dzieje, to oznaczenie funkcji zwrotnej, którą libcurl wywoła, gdy ma jakieś wyjście do zapisu z dowolnego wywołanego transferu. Możesz sprawić, by automatycznie zapisywał do pliku lub przekazać mu wskaźnik do funkcji, która sama obsłuży dane wyjściowe. Używając tej funkcji, powinieneś być w stanie złożyć różne łańcuchy wyjściowe w jeden kawałek, a następnie użyć ich w swoim programie.
Nie jestem pewien, jakie inne opcje możesz ustawić / co jeszcze wpływa na zachowanie Twojej aplikacji, więc dobrze przejrzyj tę stronę.
źródło
Oto smak C ++ akceptowanej odpowiedzi z 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; }
źródło