C libcurl wird in einen String ausgegeben

Lesezeit: 6 Minuten

Benutzeravatar von frx08
frx08

Ich möchte das Ergebnis dieser Curl-Funktion in einer Variablen speichern, wie kann ich das tun?

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

danke, ich habe es so gelöst:

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

  • Nur um darauf hinzuweisen, dass Sie in Ihrer Lösung in function_pt() die Zeichenfolge in ptr in eine Ganzzahl konvertieren, um sie in der Ausgabe wieder in eine Zeichenfolge zu konvertieren. Sie können die Zeichenfolge direkt ausgeben (und die vollständige Antwort anzeigen).

    – zzz

    19. Juni 2015 um 3:33 Uhr

  • Hier ist ein Link zum cURL-Beispiel curl.haxx.se/libcurl/c/getinmemory.html

    – lafferc

    30. Juli 2015 um 16:19 Uhr

  • CURLcode res; ist unbenutzt

    – fnc12

    17. September 2016 um 11:14 Uhr

  • Dieselbe Frage, aber für C++ anstelle von c gehen Sie hier: Save cURL content result into a string in C++

    – Trevor Boyd Smith

    4. September 2018 um 14:36 ​​Uhr


Benutzeravatar von Alex Jasmin
Alex Jasmin

Sie können eine Callback-Funktion einstellen, um eingehende Datenblöcke zu empfangen curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, myfunc);

Der Rückruf übernimmt ein benutzerdefiniertes Argument, das Sie mit festlegen können curl_easy_setopt(curl, CURLOPT_WRITEDATA, p)

Hier ist ein Codeausschnitt, der einen Puffer übergibt struct string {*ptr; len} an die Callback-Funktion und vergrößert diesen Puffer bei jedem Aufruf mit 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;
}

  • Nett. Noch schöner, wenn alle diese size_t (Außerdem len selbst) würde deklariert werden const.

    – alk

    8. Juni 2014 um 18:31 Uhr


  • für C++ std::string Gehe hier hin

    – Trevor Boyd Smith

    4. September 2018 um 14:40 Uhr

Der Benutzeravatar des Quantenphysikers
Der Quantenphysiker

Die folgende Antwort ist die C++-Methode, mit std::string, anstelle einer nullterminierten Zeichenfolge. Es verwendet immer noch eine Callback-Funktion (daran führt kein Weg vorbei), behandelt aber auch Zuordnungsfehler mit 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;
}

  • Ich denke, std::string::append kann diese Callback-Funktion viel einfacher machen.

    – Ryan Burn

    5. Dezember 2018 um 18:54 Uhr

  • @rnickb Du hast recht; s->append((char*)contents. nmemb); funktioniert bei mir einwandfrei und ist übersichtlicher. Auch die offizielle Funktionssignatur für den Rückruf hat a char* als erstes Argument, also könnten Sie das verwenden und das Casting weglassen. Und zuletzt, s->resize() initialisiert tatsächlich den neu zugewiesenen Speicherplatz. Da Sie es sowieso überschreiben wollen, s->reserve() wäre effizienter.

    – Jeinzi

    31. Januar 2019 um 14:53 Uhr

  • Das hat mir sehr geholfen. Können Sie bitte auch ein Beispiel geben, wie es mit HTTP POST geht 🙂

    – Herr Wolfenstein

    8. Januar 2020 um 15:34 Uhr

Aus dem Lesen des Handbuchs hier: http://curl.haxx.se/libcurl/c/curl_easy_setopt.html Ich denke, Sie benötigen mehrere Aufrufe von CURL_SETOPT, wobei der erste die URL ist, die Sie verarbeiten möchten, und der zweite so etwas wie:

curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, function_ptr);

Wobei function_ptr mit dieser Signatur übereinstimmt:

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

Was hier passiert, ist, dass Sie eine Rückruffunktion angeben, die libcurl aufruft, wenn es eine Ausgabe zum Schreiben von der von Ihnen aufgerufenen Übertragung hat. Sie können es dazu bringen, automatisch in eine Datei zu schreiben, oder ihm einen Zeiger auf eine Funktion übergeben, die die Ausgabe selbst verarbeitet. Mit dieser Funktion sollten Sie in der Lage sein, die verschiedenen Ausgabestrings zu einem Stück zusammenzusetzen und sie dann in Ihrem Programm zu verwenden.

Ich bin mir nicht sicher, welche anderen Optionen Sie möglicherweise festlegen müssen / was sich sonst noch auf das Verhalten Ihrer App auswirkt. Sehen Sie sich diese Seite also gut an.

Benutzeravatar von Paul Grinberg
Paul Grinberg

Hier ist eine C++-Variante der akzeptierten Antwort von 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;
}

1421940cookie-checkC libcurl wird in einen String ausgegeben

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy