সি libcurl একটি স্ট্রিং মধ্যে আউটপুট পেতে


98

আমি এই কার্ল ফাংশনের ফলাফলটি একটি চলকতে সঞ্চয় করতে চাই, আমি কীভাবে এটি করতে পারি?

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

4
কেবলমাত্র ফাংশন_পটি () তে আপনার সমাধানটি উল্লেখ করার জন্য আপনি আউটপুটটিকে স্ট্রিংয়ে ফিরে রূপান্তর করতে পিটিআর তে স্ট্রিংটিকে পূর্ণসংখ্যায় রূপান্তর করছেন। আপনি স্ট্রিংটি সরাসরি আউটপুট করতে পারেন (এবং সম্পূর্ণ প্রতিক্রিয়া দেখুন)।
zzz


4
CURLcode res;অব্যবহৃত
fnc12

4
একই প্রশ্ন তবে সি এর পরিবর্তে সি ++ এর জন্য এখানে যান: সিআরএল বিষয়বস্তুর ফলাফল সি ++ এ স্ট্রিংয়ে সংরক্ষণ করুন
ট্রেভর বয়েড স্মিথ

উত্তর:


117

আপনি ইনকামিং ডেটা অংশগুলি ব্যবহার করে কলব্যাক ফাংশন সেট করতে পারেন 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;
}

4
ভাল লাগল এমনকি খুব ভাল যদি সেগুলি size_t( lenনিজে ছাড়াও ) ঘোষণা করা হয় const
alk

4
সি ++ এর জন্য এখানেstd::string যান
ট্রেভর বয়ড স্মিথ

35

নীচের উত্তরটি std::stringনাল-টার্মিনেটেড স্ট্রিংয়ের পরিবর্তে এটি করার সি ++ উপায় । এটি এখনও একটি কলব্যাক ফাংশন ব্যবহার করে (এর আশেপাশে কোনও উপায় নেই), তবে চেষ্টা / ধরা ব্যবহার করে বরাদ্দ ত্রুটি পরিচালনা করে।

#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 :: স্ট্রিং :: অ্যাপেন্ড সেই কলব্যাক ফাংশনটিকে অনেক সহজ করে তুলতে পারে।
রায়ান বার্ন

@rnickb আপনি ঠিক বলেছেন; s->append((char*)contents. nmemb);আমার সাথে নির্দ্বিধায় কাজ করে এবং আরও সংক্ষিপ্ত। এছাড়াও, কলব্যাকের জন্য অফিসিয়াল ফাংশন স্বাক্ষরটিরchar* প্রথম যুক্তি রয়েছে, যাতে আপনি এটি ব্যবহার করতে এবং কাস্টিং বাদ দিতে পারেন। এবং শেষ অবধি, s->resize()নতুন বরাদ্দ স্থানটি আরম্ভ করে। আপনি যেভাবে যাইহোক এটি ওভাররাইট করতে চলেছেন, s->reserve()তত বেশি দক্ষ হবে।
জিনজি

এটি আমাকে অনেক সাহায্য করেছিল। কীভাবে এটি এইচটিটিপি পোস্ট দিয়ে করবেন তাও একটি উদাহরণ দিতে পারেন দয়া করে :-)
লর্ড ওল্ফেন্সটাইন

9

ম্যানুয়ালটি এখানে পড়ার থেকে: http://curl.haxx.se/libcurl/c/curl_easy_setopt.html আমার কাছে মনে হয় আপনার সিআরএল_এসটিপটিতে বেশ কয়েকটি কল প্রয়োজন, প্রথমটি আপনি যে URL টি প্রক্রিয়া করতে চান এটি হ'ল দ্বিতীয়টি এর মতো:

curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, 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;
}

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.