C语言 C libcurl 将输出转换为字符串
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2329571/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C libcurl get output into a string
提问by frx08
I want to store the result of this curl function in a variable, how can I do so?
我想将这个 curl 函数的结果存储在一个变量中,我该怎么做?
#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;
}
thanks, I solved it like this:
谢谢,我是这样解决的:
#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;
}
回答by Alex Jasmin
You can set a callback function to receive incoming data chunks using curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, myfunc);
您可以设置一个回调函数来接收传入的数据块使用 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, myfunc);
The callback will take a user defined argument that you can set using curl_easy_setopt(curl, CURLOPT_WRITEDATA, p)
回调将采用用户定义的参数,您可以使用该参数进行设置 curl_easy_setopt(curl, CURLOPT_WRITEDATA, p)
Here's a snippet of code that passes a buffer struct string {*ptr; len}to the callback function and grows that buffer on each call using realloc().
这是一段代码,它将缓冲区传递struct string {*ptr; len}给回调函数,并在每次调用时使用 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] = '#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;
}
';
}
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] = 'curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, function_ptr);
';
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;
}
回答by The Quantum Physicist
The following answer is the C++ way to do it, with std::string, instead of null-terminated string. It still uses a callback function (there's no way around it), but also handles allocation error using try/catch.
以下答案是 C++ 的方法,用std::string, 而不是以空字符结尾的字符串。它仍然使用回调函数(没有办法绕过它),但也使用 try/catch 处理分配错误。
size_t function( void *ptr, size_t size, size_t nmemb, void *stream)
回答by The Quantum Physicist
From reading the manual here: http://curl.haxx.se/libcurl/c/curl_easy_setopt.htmlI think you need several calls to CURL_SETOPT, the first being the URL you want to process, the second being something like:
从这里阅读手册:http: //curl.haxx.se/libcurl/c/curl_easy_setopt.html 我认为你需要多次调用 CURL_SETOPT,第一个是你想要处理的 URL,第二个是这样的:
#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;
}
Where function_ptr matches this signature:
其中 function_ptr 与此签名匹配:
##代码##What happens here is you denote a callback function which libcurl will call when it has some output to write from whatever transfer you've invoked. You can get it to automatically write to a file, or pass it a pointer to a function which will handle the output itself. Using this function you should be able to assemble the various output strings into one piece and then use them in your program.
这里发生的事情是你表示一个回调函数,当 libcurl 有一些输出要从你调用的任何传输写入时,它将会调用。您可以让它自动写入文件,或将指针传递给将处理输出本身的函数。使用此函数,您应该能够将各种输出字符串组合成一个片段,然后在您的程序中使用它们。
I'm not sure what other options you may have to set / what else affects how you want your app to behave, so have a good look through that page.
我不确定您可能需要设置哪些其他选项/还有什么会影响您希望应用程序的行为方式,因此请仔细浏览该页面。
回答by Paul Grinberg
Here's a C++ flavor of the accepted answer from alex-jasmin
这是alex-jasmin接受的答案的 C++ 风格
##代码##
