109 votes

C libcurl obtenir une sortie dans une chaîne

Je veux stocker le résultat de ce roulage de la fonction dans une variable, comment puis-je le faire?

#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;
}

merci, je l'ai résolu comme ceci:

#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;
  CURLcode res;
  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;
}

132voto

Alexandre Jasmin Points 18067

Vous pouvez définir une fonction de rappel pour recevoir les blocs de données à l'aide de curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, myfunc);

Le rappel de prendre un définis par l'utilisateur argument que vous pouvez définir à l'aide de curl_easy_setopt(curl, CURLOPT_WRITEDATA, p)

Voici un extrait de code qui passe un tampon struct string {*ptr; len} à la fonction de rappel et augmente que de la mémoire tampon sur chaque appel à l'aide de 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;
}

9voto

Ninefingers Points 18767

En lisant le manuel ici: http://curl.haxx.se/libcurl/c/curl_easy_setopt.html je pense que vous avez besoin de plusieurs appels à CURL_SETOPT, la première étant l'URL que vous souhaitez traiter, la deuxième étant quelque chose comme:

curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, function_ptr);

Où function_ptr correspond à cette signature:

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

Ce qui se passe ici est de vous désigner une fonction de rappel qui libcurl appellera quand il a une sortie à écrire à partir de ce que le transfert que vous avez appelé. Vous pouvez l'obtenir automatiquement les écrire dans un fichier, ou de passer un pointeur vers une fonction qui va gérer la sortie elle-même. En utilisant cette fonction, vous devriez être en mesure d'assembler les différentes chaînes de sortie en un seul morceau et ensuite les utiliser dans votre programme.

Je ne suis pas sûr de ce que d'autres options que vous pourriez avoir à régler / quoi d'autre affecte la façon dont vous voulez que votre application se comporter, alors jetez un bon coup d'oeil par le biais de cette page.

1voto

trav1th Points 104

J'avais été confronté à un problème similaire. Je recevais ce message d'erreur:

* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Content-Type: text/plain
< Accept-Ranges: bytes
< ETag: "3084120343"
< Last-Modified: Thu, 03 Apr 2014 22:23:51 GMT
< Content-Length: 10
< Connection: close
< Date: Thu, 10 Apr 2014 23:33:08 GMT
< Server: EC2ws
<
* Failed writing body (0 != 10)
* Closing connection #0
* Failed writing received data to disk/application

Le problème a été le retour de la fonction de rappel. Nous le disions return 0; où nous aurions été de retourner la longueur de l'écrit--Alexandre posté, return size*nmemb;.

Merci @Alexandre

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X