gpt4 book ai didi

c++ - 使用 libcurl : it does not appear to get the entire page 时出现问题

转载 作者:太空宇宙 更新时间:2023-11-03 10:21:26 27 4
gpt4 key购买 nike

我很难开始使用 libcurl。下面的代码似乎没有从指定的 URL 检索整个页面。我哪里错了?

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <curl/curl.h>
#include <curl/types.h>
#include <curl/easy.h>

using namespace std;

char buffer[1024];

size_t tobuffer(char *ptr, size_t size, size_t nmemb, void *stream)
{
strncpy(buffer,ptr,size*nmemb);
return size*nmemb;
}

int main() {
CURL *curl;
CURLcode res;


curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "http://google.co.in");
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION,1);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &tobuffer);

res = curl_easy_perform(curl);

printf("%s",buffer);

curl_easy_cleanup(curl);
}
return 0;
}

最佳答案

如图所示 at the libcurl documentation for curl_easy_setopt() ,回调函数会根据需要多次调用,以传送所获取页面的所有字节。

您的函数在每次调用时都会覆盖相同的缓冲区,结果是在 curl_easy_perform() 完成获取文件后,您只能在对 tobuffer() 的最终调用中使用适合的内容 离开了。

简而言之,您的函数 tobuffer() 必须做一些事情,而不是在每次调用时覆盖相同的缓冲区。

更新

例如,您可以执行类似以下完全未经测试的代码:

struct buf {
char *buffer;
size_t bufferlen;
size_t writepos;
} buffer = {0};

size_t tobuffer(char *ptr, size_t size, size_t nmemb, void *stream)
{
size_t nbytes = size*nmemb;
if (!buffer.buffer) {
buffer.buffer = malloc(1024);
buffer.bufferlen = 1024;
buffer.writepos = 0;
}
if (buffer.writepos + nbytes < buffer.bufferlen) {
buffer.bufferlen = 2 * buffer.bufferlen;
buffer.buffer = realloc(buffer, buffer.bufferlen);
}
assert(buffer.buffer != NULL);
memcpy(buffer.buffer+buffer.writepos,ptr,nbytes);
return nbytes;
}

稍后在您的程序中您将需要像这样释放分配的内存:

void freebuffer(struct buf *b) {
free(b->buffer);
b->buffer = NULL;
b->bufferlen = 0;
b->writepos = 0;
}

另外,请注意,我使用 memcpy() 而不是 strncpy() 将数据移动到缓冲区。这一点很重要,因为 libcurl 没有声明传递给回调函数的数据实际上是一个以 NUL 结尾的 ASCII 字符串。特别是,如果您检索一个 .gif 图像文件,它肯定可以(并且将)在您希望保留在缓冲区中的文件中包含零字节。 strncpy() 将在它在源数据中看到第一个 NUL 后停止复制。

作为读者的练习,我将所有错误处理都留在了这段代码之外。您必须 放入一些。此外,如果对 realloc() 的调用失败,我还会留下大量内存泄漏。

另一个改进是使用允许回调的 stream 参数值来自 libcurl 调用者的选项。这可用于在不使用全局变量的情况下分配管理缓冲区。我也强烈建议这样做。

关于c++ - 使用 libcurl : it does not appear to get the entire page 时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3573146/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com