CURLOPTS内容的c++rapidjson解析错误

c++ rapidjson parse error of CURLOPTS content

本文关键字:错误 c++rapidjson CURLOPTS      更新时间:2023-10-16

我试图反序列化从CURLOPTS获得的json对象,但我得到了一个解析错误(错误的数据类型)。如何将JSON转换为标准的c++对象或可读变量?

代码:

darknet064tokyo rapidjson # cat testGetprice.cpp
#include "include/rapidjson/document.h"
#include <iostream>
#include <stdio.h>
#include <curl/curl.h>
#include <unistd.h>
#include <unordered_map>
using namespace rapidjson;
size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream) {
        size_t written;
        written = fwrite(ptr, size, nmemb, stream);
        return written;
}
//function to get coin data and perform analysis
int getData()
{
        int count = 0;
        //begin non terminating loop
        while(true)
        {
                count++;
                CURL *curl;
                CURLcode res;
                curl = curl_easy_init();
                if(curl) {
                        curl_easy_setopt(curl, CURLOPT_URL, "http://pubapi.cryptsy.com/api.php?method=singlemarketdata&marketid=155");
                        /* 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: %sn",
                                curl_easy_strerror(res));
                        //begin deserialization
                        Document document;
                        document.Parse(res);
                        assert(document.HasMember("lasttradeprice"));
                        assert(document["hello"].IsString());
                        printf("The Last Traded Price is = %sn", document["lasttradeprice"].GetString());

                        FILE * pFile;
                        pFile = fopen ("/home/coinz/cryptsy/myfile.txt","a+");
                        if (pFile!=NULL)
                        {
                                curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
                                curl_easy_setopt(curl, CURLOPT_WRITEDATA, pFile);
                                res = curl_easy_perform(curl);
                                //std::cout << pFile << std::endl;
                                fprintf(pFile, "n");
                                fclose (pFile);
                        }
                        /* always cleanup */
                        curl_easy_cleanup(curl);
                //timer for URL request.  *ADUJST ME AS DESIRED*
                usleep(10000000);
                }
        }
        return 0;
}
//Le Main
int main(void){
        getData();
}

错误代码输出:

darknet064tokyo rapidjson # g++ -g testGetprice.cpp -o testGetprice.o -std=gnu++11
testGetprice.cpp: In function 'int getData()':
testGetprice.cpp:36:22: error: no matching function for call to 'rapidjson::GenericDocument<rapidjson::UTF8<> >::Parse(CURLcode&)'
testGetprice.cpp:36:22: note: candidates are:
In file included from testGetprice.cpp:1:0:
include/rapidjson/document.h:1723:22: note: template<unsigned int parseFlags, class SourceEncoding> rapidjson::GenericDocument& rapidjson::GenericDocument::Parse(const Ch*) [with unsigned int parseFlags = parseFlags; SourceEncoding = SourceEncoding; Encoding = rapidjson::UTF8<>; Allocator = rapidjson::MemoryPoolAllocator<>; StackAllocator = rapidjson::CrtAllocator]
include/rapidjson/document.h:1723:22: note:   template argument deduction/substitution failed:
testGetprice.cpp:36:22: note:   cannot convert 'res' (type 'CURLcode') to type 'const Ch* {aka const char*}'
In file included from testGetprice.cpp:1:0:
include/rapidjson/document.h:1734:22: note: template<unsigned int parseFlags> rapidjson::GenericDocument& rapidjson::GenericDocument::Parse(const Ch*) [with unsigned int parseFlags = parseFlags; Encoding = rapidjson::UTF8<>; Allocator = rapidjson::MemoryPoolAllocator<>; StackAllocator = rapidjson::CrtAllocator]
include/rapidjson/document.h:1734:22: note:   template argument deduction/substitution failed:
testGetprice.cpp:36:22: note:   cannot convert 'res' (type 'CURLcode') to type 'const Ch* {aka const char*}'
In file included from testGetprice.cpp:1:0:
include/rapidjson/document.h:1741:22: note: rapidjson::GenericDocument<Encoding, Allocator, StackAllocator>& rapidjson::GenericDocument<Encoding, Allocator, StackAllocator>::Parse(const Ch*) [with Encoding = rapidjson::UTF8<>; Allocator = rapidjson::MemoryPoolAllocator<>; StackAllocator = rapidjson::CrtAllocator; rapidjson::GenericDocument<Encoding, Allocator, StackAllocator> = rapidjson::GenericDocument<rapidjson::UTF8<> >; rapidjson::GenericDocument<Encoding, Allocator, StackAllocator>::Ch = char]
include/rapidjson/document.h:1741:22: note:   no known conversion for argument 1 from 'CURLcode' to 'const Ch* {aka const char*}'

注意你正在做的事情。curl_easy_perform()返回错误代码,而不是服务器的响应数据。您将Curl的错误代码传递给Document::Parse(),而不是实际的JSON数据。错误消息正是在告诉你:

错误:调用"rapidjson::GenericDocument>::Parse(CURLcode&)"没有匹配的函数

默认情况下,curl_easy_perform()将接收到的数据输出到stdout。要覆盖它以便您可以在代码中接收JSON数据,您需要使用curl_easy_setopt()来分配一个自定义CURLOPT_WRITEFUNCTION回调,该回调将接收到的数据写入您使用CURLOPT_WRITEDATA指定的缓冲区/字符串。您已经在这样做了,但您正在将数据写入文件,而不是写入内存缓冲区/字符串。

这种情况在libcurl教程的"处理轻松的libcurl"部分进行了讨论。

试试类似的东西:

#include "include/rapidjson/document.h"
#include <iostream>
#include <stdio.h>
#include <curl/curl.h>
#include <unistd.h>
#include <unordered_map>
#include <string>
using namespace rapidjson;
struct myData
{
    std::fstream *file;
    std::string *str;
};
size_t write_data(void *ptr, size_t size, size_t nmemb, myData *data)
{
    size_t numBytes = size * nmemb;
    if (data->file)
        data->file->write((char*)ptr, numBytes);
    if (data->str)
        *(data->str) += std::string((char*)ptr, numBytes);
    return numBytes;
}
//function to get coin data and perform analysis
int getData()
{
    int count = 0;
    //begin non terminating loop
    while(true)
    {
        count++;
        CURL *curl = curl_easy_init();
        if (curl)
        {
            curl_easy_setopt(curl, CURLOPT_URL, "http://pubapi.cryptsy.com/api.php?method=singlemarketdata&marketid=155");
            std::fstream file("/home/coinz/cryptsy/myfile.txt", ios_base::out | ios_base::ate);
            std::string json;
            myData data;
            data.file = &file;
            data.str = &json;
            curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &write_data);
            curl_easy_setopt(curl, CURLOPT_WRITEDATA, &data);
            /* Perform the request, res will get the return code */
            CURLcode res = curl_easy_perform(curl);
            /* Check for errors */
            if (res != CURLE_OK)
            {
                std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << std::endl;
            }
            else
            {
                file << std::endl;
                //begin deserialization
                Document document;
                document.Parse(json.c_str());
                assert(document.HasMember("lasttradeprice"));
                assert(document["hello"].IsString());
                std::cout << "The Last Traded Price is = " << document["lasttradeprice"].GetString() << std::endl;
            }
            /* always cleanup */
            curl_easy_cleanup(curl);
        }
        //timer for URL request.  *ADUJST ME AS DESIRED*
        usleep(10000000);
    }
    return 0;
}
//Le Main
int main(void)
{
    getData();
}