现代C++的libcurl和JSON问题



我试图通过编写一个简单的程序来自学C++,该程序将cURL请求发送到JSON API,解析数据,然后将其存储在文本文档或数据库中供Web应用程序访问。我已经在 PHP 中完成了这项任务,并认为C++不会更难,但我什至无法让 cURL 返回字符串并显示它。

我得到这个编译没有错误,但响应"JSON data: "没有显示任何 JSON 数据应该在的位置。

我哪里做错了?URL-to-API是实际的URL,所以我相信我使用了错误的setopt函数,或者没有设置一个。在 PHP 中,"CURLOPT_RETURNTRANSFER"让它作为字符串返回,但我收到一个错误:

错误:"CURLOPT_RETURNTRANSFER"未在此范围内
声明curl_easy_setopt(curl、CURLOPT_RETURNTRANSFER、true(;

我在 Ubuntu 上使用 g++ 编译器,并在命令行参数中添加了-lcurl

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <string>
#include <curl/curl.h>
//#include "json.hpp"
using namespace std;
//using json = nlohmann::json;
size_t WriteCallback(char *contents, size_t size, size_t nmemb, void *userp) {
((std::string*)userp)->append((char*)contents, size * nmemb);
return size * nmemb;
}
string getJSON(string URL) {
CURL *curl;
CURLcode res;
string readBuffer;
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_HEADER, 1);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, true); // follow redirect
//curl_easy_setopt(curl, CURLOPT_RETURNTRANSFER, true); // return as string
curl_easy_setopt(curl, CURLOPT_HEADER, false);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_URL, URL);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);     
res = curl_easy_perform(curl);
/* always cleanup */
curl_easy_cleanup(curl);
return readBuffer;
}
return 0;
}
int main() {
string data = getJSON("URL-to-api");
cout << "JSON Data: n" << data;
return 0;
}

当我取消注释现代C++包含和命名空间行的 JSON 时,出现此错误:

error 此文件需要 ISO C++ 2011 标准的编译器和库支持。必须使用 -std=c++11 或 -std=gnu++11 编译器选项启用此支持。

以及该库中函数的一系列错误。在开始这个项目之前,我刚刚下载了最新版本的 g++,那么我需要做什么?

我在 Ubuntu 上使用 g++ 5.4.0。

更新:

所以我在res = curl_easy_perform(curl)下添加了一个检查,它不会返回错误消息,res显示为6.这似乎比应该困难得多:

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <string>
#include <curl/curl.h>
//#include "json.hpp"
using namespace std;
//using json = nlohmann::json;
size_t WriteCallback(char *contents, size_t size, size_t nmemb, void *userp) {
((std::string*)userp)->append((char*)contents, size * nmemb);
return size * nmemb;
}
string getJSON(string URL) {
CURL *curl;
CURLcode res;
string readBuffer;
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_HEADER, 1);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, true); // follow redirect
curl_easy_setopt(curl, CURLOPT_HEADER, false);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_URL, URL);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);     
res = curl_easy_perform(curl);
cout << res << endl;
if (!res) {
cout << "cURL didn't workn";
}
/* always cleanup */
curl_easy_cleanup(curl);
curl = NULL;
return readBuffer;
}
}
int main() {
string data = getData("");
cout << "JSON Data: n" << data;
return 0;
}

运行程序时,我得到以下输出:

6 JSON数据:

在 PHP 中,"CURLOPT_RETURNTRANSFER"将其作为字符串返回,但我收到一个错误:

错误:"CURLOPT_RETURNTRANSFER"未在此范围内
声明 curl_easy_setopt(卷曲,CURLOPT_RETURNTRANSFER,真(;

没有记录curl_easy_setopt()CURLOPT_RETURNTRANSFER选项。 我认为这是为 PHP 的curl_exec()函数指定的一个选项,该函数在 CURL 本身中不存在。 在这种情况下,CURLOPT_WRITEFUNCTION是正确的方法。

当我取消注释现代C++包含和命名空间行的 JSON 时,我得到:

error 此文件需要 ISO C++ 2011 标准的编译器和库支持。必须使用 -std=c++11 或 -std=gnu++11 编译器选项启用此支持。

该错误是不言自明的。 您的 JSON 库需要 C++11,但您未在启用 C++11 的情况下进行编译。 某些新式编译器仍默认使用较旧的C++版本(通常为C++98(,并要求您在命令行或项目 makefile 配置中调用编译器时显式启用 C++11(或更高版本(。

在 g++ 的情况下,当前版本 (8.2( 默认为 C17 表示 C,C++14 表示 C++,如果未通过-std参数另行指定。 您的版本(5.4(分别默认为(GNU方言(C11和C++98。

更新:您的代码中还有其他错误:

  1. 您正在将一个std::string对象传递给curl_easy_setopt(),其中需要char*指针用于CURLOPT_URL。 您需要更改此设置:

    curl_easy_setopt(curl, CURLOPT_URL, URL);
    

    对此:

    curl_easy_setopt(curl, CURLOPT_URL, URL.c_str());
    
  2. 您没有正确测试curl_easy_perform()的返回值。 根据文档,curl_easy_perform()在成功时返回 0 (CURLE_OK(,在错误时返回非零,因此您需要更改以下内容:

    if (!res)
    

    对此:

    if (res != CURLE_OK)
    
  3. 所以我在res = curl_easy_perform(curl)...下添加了一个检查,res显示为6

    这是CURLE_COULDNT_RESOLVE_HOST,这是有道理的,因为您更新的示例正在向getJSON()传递一个空白URL

    string data = getJSON(""); // should be "URL-to-api" instead!
    

最新更新