如何在C++中从curl读取到字符串流?

问题描述 投票:0回答:1

我正在使用 Web API,读取稍后处理的文本数据。有时数据相当大,例如 90 MB。我正在尝试将其读入

std::stringstream
,因此稍后我可以使用
std::string
将每一行放入
std::getline()

但是,当我使用带有curl的stringstream时,我无法使其工作:

#include <iostream> 
#include <sstream> 
#include <string>
#include <curl/curl.h>

static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp) {
    size_t realsize = size * nmemb;
    std::stringstream *stream=(std::stringstream *)userp;
    return realsize;
}

int main(int argc, char* argv[]) { 
    CURL *curl;
    CURLcode res;
    std::stringstream stream;
    curl = curl_easy_init();
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_URL, "http://date.jsontest.com/"); // simple, small example
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&stream);
        res = curl_easy_perform(curl);
        curl_easy_cleanup(curl);
    }
    std::cout << "[" << stream.str() << "]" << std::endl;
    // the loop with getline() would enter here
    return 0;
}

输出:

[]

我改编了here的代码,并注意到他们使用了

istream
,但如果我尝试,我会收到编译器错误:
basic_istream is protected within this context

我尝试在

istream
中使用
stringstream
而不是
WriteMemoryCallback
,并尝试从
(void*)
回调中删除
CURLOPT_WRITEDATA
,但它最终总是给出一个空流。

我知道我可以使用字符串来代替,但我认为使用

getline()
可能比自己处理字符串以将行分开更快。

我还尝试从curl读取到一个字符串,然后将该字符串传递给一个流,然后传递给getline,但随后我复制了整个字符串,这效率不高。

如何将数据从curl获取到流中,然后通过getline()从那里获取到字符串?

编辑

回调比较常见的代码是

static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp) {
    ((std::string*)userp)->append((char*)contents, size * nmemb);
    return size * nmemb;
}

现在我发现我的功能离它还很远。但我仍然不知道如何将新值附加到字符串流。

c++ string curl stream
1个回答
0
投票

WriteMemoryCallback()
没有在
stringstream
中写入任何内容,这就是为什么你得到空输出。

试试这个:

static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp) {
    size_t realsize = size * nmemb;
    std::stringstream *stream =(std::stringstream *)userp;

    // ADD THIS! 
    stream->write(contents, realsize);

    return realsize;
} 
© www.soinside.com 2019 - 2024. All rights reserved.