C libcurl get output into a string C libcurl get output into a string c c

C libcurl get output into a string


You can set a callback function to receive incoming data chunks using curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, myfunc);

The callback will take a user defined argument that you can set using curl_easy_setopt(curl, CURLOPT_WRITEDATA, p)

Here's a snippet of code that passes a buffer struct string {*ptr; len} to the callback function and grows that buffer on each call using 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;}


The following answer is the C++ way to do it, with std::string, instead of null-terminated string. It still uses a callback function (there's no way around it), but also handles allocation error using 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;}


From reading the manual here: http://curl.haxx.se/libcurl/c/curl_easy_setopt.html I think you need several calls to CURL_SETOPT, the first being the URL you want to process, the second being something like:

curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, function_ptr);

Where function_ptr matches this signature:

size_t function( void *ptr, size_t size, size_t nmemb, void *stream)

What happens here is you denote a callback function which libcurl will call when it has some output to write from whatever transfer you've invoked. You can get it to automatically write to a file, or pass it a pointer to a function which will handle the output itself. Using this function you should be able to assemble the various output strings into one piece and then use them in your program.

I'm not sure what other options you may have to set / what else affects how you want your app to behave, so have a good look through that page.