putting CURL result in a string and not STDOUT?

2020-03-30 05:02发布

问题:

I have the following curl code, which make a request to website and retrieve data from it, it works well, but I want to store my data in a string and not in the output window. Any idea?

#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, "http://api.hostip.info/get_html.php?ip=xxx.xxx.xx.xxx");
    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
    res = curl_easy_perform(curl);
    if(res != CURLE_OK)
      fprintf(stderr, "curl_easy_perform() failed: %s\n",
              curl_easy_strerror(res));
    curl_easy_cleanup(curl);
  }
  return 0;
}

回答1:

int http_get_response(void *buffer, size_t size, size_t rxed, char **msg_in)
{
    char *c;

    if (asprintf(&c, "%s%.*s", *msg_in, size * rxed, buffer) == -1) {
        free(*msg_in);
        msg_in = NULL;
        return -1;
    }

    free(*msg_in);
    *msg_in = c;

    return size * rxed;
}

and add the following curl option in your main

char *msg_in = calloc(1,sizeof(char));

curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, http_get_response);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &msg_in);

Then you will get the message in the msg_in

EDIT

do not forget to free msg_in when it become uselless in your program

free(msg_in); msg_in = NULL;


回答2:

A a general (non-curl specific) method, change your standard output (path 1) (or standard error: path 2) path(s) prior to calling curl. Read the man page on dup2 to see how to duplicate a path to a specific descriptor, and the fdopen function to get a FILE * out of it.

The idea is you first dup path 1 for stdout, and/or 2 for stderr, to save copies of them somewhere. You then close the original paths. You create a pipe (man pipe) and then dup2 the second channel of the pipe to path 1 (or 2). You can now read() from the first channel of the pipe to get the output that was placed there.



回答3:

Try this:

curl_easy_setopt(curl, CURLOPT_RETURNTRANSFER, true);