C libcurl एक स्ट्रिंग में आउटपुट प्राप्त करता है


94

मैं इस कर्ल फ़ंक्शन के परिणाम को एक चर में संग्रहीत करना चाहता हूं, मैं ऐसा कैसे कर सकता हूं?

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

धन्यवाद, मैंने इसे इस तरह हल किया:

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

1
बस अपने समाधान में function_pt () में इंगित करने के लिए आप इसे ptr में पूर्णांक में स्ट्रिंग में परिवर्तित कर रहे हैं ताकि इसे आउटपुट में स्ट्रिंग में बदल सकें। आप सीधे स्ट्रिंग को आउटपुट कर सकते हैं (और पूर्ण प्रतिक्रिया देखें)।
zzz

2
यहाँ cURL उदाहरण के लिए एक लिंक है curl.haxx.se/libcurl/c/getinmemory.html
lafferc

1
CURLcode res;अप्रयुक्त है
fnc12

एक ही सवाल है, लेकिन सी + + के बजाय सी के लिए यहाँ जाएँ: सी + + में एक स्ट्रिंग में सीयूआरएल सामग्री परिणाम सहेजें
ट्रेवर बोयड स्मिथ

जवाबों:


114

आप आने वाले डेटा का उपयोग करके कॉलबैक फ़ंक्शन सेट कर सकते हैं curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, myfunc);

कॉलबैक एक उपयोगकर्ता परिभाषित तर्क लेगा जिसे आप उपयोग कर सकते हैं curl_easy_setopt(curl, CURLOPT_WRITEDATA, p)

यहां कोड का एक स्निपेट struct string {*ptr; len}है जो कॉलबैक फ़ंक्शन के लिए एक बफर पास करता है और रियललॉक () का उपयोग करके प्रत्येक कॉल पर उस बफर को बढ़ता है।

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

1
अच्छा लगा। यहां तक ​​कि अगर सभी size_t(इसके अलावा len) घोषित किया जाए तो भी अच्छा होगा const
alk


33

निम्नलिखित उत्तर std::stringअशक्त-समाप्त स्ट्रिंग के बजाय, इसे करने का C ++ तरीका है । यह अभी भी एक कॉलबैक फ़ंक्शन (इसके आसपास कोई रास्ता नहीं है) का उपयोग करता है, लेकिन कोशिश / कैच का उपयोग करके आवंटन त्रुटि को भी संभालता है।

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

मुझे लगता है कि std :: string :: append उस कॉलबैक फ़ंक्शन को बहुत सरल बना सकता है।
rnickb

@ क्रिकब यू आर राइट; s->append((char*)contents. nmemb);मेरे साथ निर्दोष रूप से काम करता है और अधिक संक्षिप्त है। इसके अलावा, कॉलबैक के लिए आधिकारिक फ़ंक्शन हस्ताक्षरchar* में पहला तर्क है, इसलिए आप इसका उपयोग कर सकते हैं और कास्टिंग को छोड़ सकते हैं। और अंत में, s->resize()वास्तव में नव आवंटित स्थान को इनिशियलाइज़ करता है। जैसा कि आप वैसे भी इसे अधिलेखित करने वाले हैं, s->reserve()अधिक कुशल होगा।
14

इसने मेरी बहुत मदद की। क्या आप इसका एक उदाहरण भी दे सकते हैं कि इसे HTTP POST के साथ कैसे करें :-)
लॉर्ड वोल्फेंस्टीन

9

यहाँ मैनुअल पढ़ने से: http://curl.haxx.se/libcurl/c/curl_easy_setopt.html मुझे लगता है कि आपको CURL_SETOPT को कई कॉल की आवश्यकता है, पहला URL जिसे आप प्रोसेस करना चाहते हैं, दूसरा कुछ इस तरह है:

curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, function_ptr);

जहां function_ptr इस हस्ताक्षर से मेल खाता है:

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

यहाँ क्या होता है आप एक कॉलबैक फ़ंक्शन को सूचित करते हैं जो कि libcurl कॉल करेगा जब आपके पास जो भी ट्रांसफर किया गया है, उसमें से कुछ आउटपुट लिखने के लिए है। आप इसे किसी फ़ाइल में स्वचालित रूप से लिखने के लिए प्राप्त कर सकते हैं, या इसे एक फ़ंक्शन को पॉइंटर पास कर सकते हैं जो आउटपुट को स्वयं संभाल लेगा। इस फ़ंक्शन का उपयोग करके आपको विभिन्न आउटपुट स्ट्रिंग्स को एक टुकड़े में इकट्ठा करने में सक्षम होना चाहिए और फिर उन्हें अपने प्रोग्राम में उपयोग करना चाहिए।

मुझे यकीन नहीं है कि आपको अन्य विकल्पों के लिए क्या सेट करना पड़ सकता है / और क्या प्रभावित करता है कि आप अपने ऐप को कैसे व्यवहार करना चाहते हैं, इसलिए उस पृष्ठ के माध्यम से एक अच्छा नज़र डालें।


0

यहां एलेक्स-जस्मीन से स्वीकृत जवाब का सी ++ स्वाद है

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.