我正在尝试通过编写一个简单的程序来自学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;
}
当我取消对Modern C ++包含和名称空间行的JSON的注释时,出现此错误:
错误此文件需要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 work\n";
}
/* always cleanup */
curl_easy_cleanup(curl);
curl = NULL;
return readBuffer;
}
}
int main() {
string data = getData("");
cout << "JSON Data: \n" << data;
return 0;
}
运行程序时,我得到以下输出:
6 JSON Data:
答案 0 :(得分:1)
在PHP中,“ CURLOPT_RETURNTRANSFER”使它作为字符串返回,但出现错误:
错误:未在此范围内声明“ CURLOPT_RETURNTRANSFER”
curl_easy_setopt(curl,CURLOPT_RETURNTRANSFER,true);
没有为curl_easy_setopt()
记录的CURLOPT_RETURNTRANSFER
选项。我认为这是为PHP的curl_exec()
函数指定的一个选项,CURL本身不存在此函数。 CURLOPT_WRITEFUNCTION
是在这种情况下的正确方法。
当我取消注释现代C ++的JSON包含和命名空间行时,我得到:
错误此文件需要ISO C ++ 2011标准的编译器和库支持。必须使用-std = c ++ 11或-std = gnu ++ 11编译器选项启用此支持。
该错误是不言自明的。您的JSON库需要C ++ 11,但是您未在启用C ++ 11的情况下进行编译。一些现代的编译器仍默认使用较旧的C ++版本(通常是 C ++ 98),并要求您在命令行或您的命令行中调用编译器时显式启用C ++ 11(或更高版本)。项目makefile配置。
对于g ++,如果未通过-std
参数另外指定,则当前版本(8.2)默认为C的C17(GNU方言)和C ++的默认C ++ 14。您的版本(5.4)分别默认为C11和C ++ 98(的GNU方言)。
更新:您的代码中还有其他错误:
您正在将std::string
对象传递到curl_easy_setopt()
,其中char*
应该使用CURLOPT_URL
指针。您需要更改此内容:
curl_easy_setopt(curl, CURLOPT_URL, URL);
为此:
curl_easy_setopt(curl, CURLOPT_URL, URL.c_str());
您没有正确测试curl_easy_perform()
的返回值。根据文档,curl_easy_perform()
成功返回0(CURLE_OK
),错误返回非零,因此您需要更改此值:
if (!res)
为此:
if (res != CURLE_OK)
因此我在
res = curl_easy_perform(curl)
...下添加了一个支票,并且res
显示为6
。
即CURLE_COULDNT_RESOLVE_HOST
,这很有意义,因为您更新的示例将空白URL
传递给getJSON()
:
string data = getJSON(""); // should be "URL-to-api" instead!