MFC程序中获取实时汇率(用于汇率转换功能)

 记录完成MFC大作业中遇到的问题和一些解决办法。调用的API来源为23、实时汇率API接口,免费好用_roll圈圈的博客-CSDN博客_汇率api;用到的库有curl、nlohmann_json。

参考文章

Visual Studio(VS2017)编译并使用curl C/C++ HTTP GET POST libcurl(二、调用示例)_路过人间本尊的博客-CSDN博客_vs2017编译curl

VS2022编译和使用curl网络库_含影的博客-CSDN博客_curl vs 编译 

c++ 使用nlohmann_json库解析json文件_山水一的博客-CSDN博客 

libcurl使用easy模式阻塞卡死等问题的完美解决---超时设置_指尖上星空的博客-CSDN博客_libcurl 超时

一、curl、nlohmann_json库的VS环境配置

1.curl

这里用到curl库,需要自己编译(也有编译好的库)和VS环境配置。一开始想用自己编译的curl库,但bat文件无法再电脑上运行,用Shell运行会报错:Error: This batch file should only be used with a curl git repository。后来改用编译好的库成功配置好环境。

已编译好的库下载,这里用的适用VS2019-2022,debug x64,其他配置可以返回父目录下载。windows.php.net - /downloads/php-sdk/deps/vs16/x64/

将下载文件夹中的 include 和 lib 文件夹复制到工程目录下(若附加多个库,建议外面套一个文件夹命名为curl,防止混乱)

2.nlohmann_json

GitHub - nlohmann/json: JSON for Modern C++

下载 nlohmann_json,复制其中的三个文件夹 include、single_include、tests 到工程目录下(同样建议外面套一个文件夹命名为nlohmann_json)。

3.VS环境配置

然后是修改工程属性。在解决方案资源管理器找到项目(图中为calculator),右键弹出选项,选择“属性”。

MFC程序中获取实时汇率(用于汇率转换功能)_第1张图片

注意:

以下两个目录位置可能有出入,根据你之前复制的库文件的路径写即可;

$(ProjectDir)\ :这个前缀含义是在项目文件中查找,用这个可以防止工程文件移动带来的找不到库文件的问题。

【VC++目录】--【包含目录】
$(ProjectDir)\include;$(ProjectDir)\nlohmannjson\single_include;$(ProjectDir)\nlohmannjson\include;$(IncludePath)
【VC++目录】--【库目录】
$(ProjectDir)\lib;$(ProjectDir)\bin;$(ProjectDir)\nlohmannjson\tests\thirdparty\doctest;$(ProjectDir)\nlohmannjson\tests\thirdparty\fifo_map;$(LibraryPath)

【链接器】--【输入】--【附加依赖项】
//(curl库的)
libcurl_a.lib
Ws2_32.lib
Wldap32.lib
winmm.lib
Crypt32.lib
Normaliz.lib
//(nlohmannjson的)
kernel32.lib
user32.lib
gdi32.lib
winspool.lib
shell32.lib
ole32.lib
oleaut32.lib
uuid.lib
comdlg32.lib
advapi32.lib

【C/C++】--【预处理器】
CURL_STATICLIB        //用于配置curl环境
_CRT_SECURE_NO_WARNINGS   //解决fopen不安全的问题

二、向网页API发送请求,写入文件

void get_api_to_file()		//从网页api获取汇率信息并写入json文件
{
	CURL* curl = NULL;
	CURLcode res = CURLE_OK;
	FILE* fp;
	fp = fopen("rate.json", "w");
	struct curl_slist* headers = NULL;
	headers = curl_slist_append(headers, "charsets = utf-8");    //加了这个命令行还是会出现中文乱码,这里暂时也没有好的解决办法

	curl_global_init(CURL_GLOBAL_ALL);

	//初始化easy handler句柄  
	curl = curl_easy_init();
	if (curl) {
		//设置post请求的url地址  
		curl_easy_setopt(curl, CURLOPT_URL, "这里填网页API的URL");
		//设置HTTP头  
		curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
		//写入文件fp
		curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
		//设置发送超时时间,防止出现阻塞(easy模式会有阻塞情况)
		curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3);

		//执行单条请求  
		res = curl_easy_perform(curl);
		if (res != CURLE_OK) {
			//curl_easy_strerror进行出错打印  
			fprintf(stderr, "curl_easy_perform() failed: %s\n",
				curl_easy_strerror(res));
		}

		curl_slist_free_all(headers);

		//这个调用用来结束一个会话.与curl_easy_init配合着用  
		curl_easy_cleanup(curl);

		//在结束libcurl使用的时候,用来对curl_global_init做的工作清理。类似于close的函数  
		curl_global_cleanup();
		fclose(fp);
	}
	return;
}

三、对Json文件解析

 从API获取到的数据是Json格式,需要进行解析方便使用。

在头文件中先根据API的json样式定义好结构体。

//准备好带解析汇率信息的格式
struct rate_unit
{
	string name;
	string nameDesc;
	string from;
	string to;
	string price;

	CString fromDesc;
	CString toDesc;
};

struct all
{
	int code;
	string msg;
	rate_unit rate_[24];
	int size;
};

在.cpp中重载解析json的函数

//以下两个from_json函数是为了解析从网页api获取含汇率信息的json文件
void from_json(const json& j, all& a)
{
	j.at("code").get_to(a.code);
	j.at("msg").get_to(a.msg);
	for (int i = 0; i < j["data"].size(); i++)
	{
		a.rate_[i].name = j["data"][i].at("name");
		a.rate_[i].nameDesc = j["data"][i].at("nameDesc");
		a.rate_[i].from = j["data"][i].at("from");
		a.rate_[i].to = j["data"][i].at("to");
		a.rate_[i].price = j["data"][i].at("price");
	}
	a.size = j["data"].size();
}
void from_json(const json& j, rate_unit& d)
{
	j.at("name").get_to(d.name);
	j.at("nameDesc").get_to(d.nameDesc);
	j.at("from").get_to(d.from);
	j.at("to").get_to(d.to);
	j.at("price").get_to(d.price);
}

 将其解析,数据储存在all类型结构体s内

    get_api_to_file();

	ifstream jfile("rate.json");
	json nj;
	jfile >> nj;

	//解析json文件到all类型的struct
	from_json(nj, s);

你可能感兴趣的:(mfc,c++)