前言:这个东西是八月份自己捣鼓着玩的 现记录下
需要解决的问题:
1.选择对应的接口(稳定,最好使用官方提供的)
2.获取数据
2.对返回数据的处理
问题1:天气接口的获取
=>通过城市名 来获取当前城市的温度以及未来一周的天气变化(Json数据) [返回数据为乱码]
接口:http://wthrcdn.etouch.cn/weather_mini?city=北京市
=>通过城市ID来获取当前城市温度以及未来一周的天气变化(Json数据) [返回数据为乱码]
接口:http://wthrcdn.etouch.cn/weather_mini?citykey=101010100
城市ID:
=> 通过城市获取当前的一些信息(返回XML数据) [返回数据正确]
接口:http://wthrcdn.etouch.cn/WeatherApi?city=北京市
=> 通过城市id(101010100)获取当前城市温度、湿度、空气质量主要参数指数、警告、昨日天气、未来天气、日出日落时间((⊙﹏⊙)b)(XML数据):
接口:http://wthrcdn.etouch.cn/WeatherApi?citykey=101010100
=> 良心API 提供了PM2.5、温度、湿度、ip查询、快递查询接口
接口:http://api.help.bj.cn/api/
http://api.help.bj.cn/apis/weather6d/?id=101280601 //根据ID来访问的一个接口
问题2 如何从页面上获取到返回数据
CInternetSession session(L"HttpClient");
CString url = L"http://api.help.bj.cn/apis/weather6d/?id=101060101";
//CString url = L"http://wthrcdn.etouch.cn/weather_mini?city=北京市";
CHttpFile* pfile = (CHttpFile *)session.OpenURL(url);
DWORD dwStatusCode;
pfile->QueryInfoStatusCode(dwStatusCode);
CString BackStringData = L"";
if (dwStatusCode == HTTP_STATUS_OK)
{
CString data = L"";
while (pfile->ReadString(data))
{
BackStringData += data;
}
}
pfile->Close();
delete pfile;
session.Close();
补充:
使用libcurl提供的接口 更快的访问或者上传数据libcurl在https的协议下报错
原因:安装openssl
问题3 获取的数据都是乱码的,但是写入文本可以正常显示
这个问题出现的原因:因为系统的编码方式与得到文件的编码方式不同导致的乱码
解决方案:根据我们得到数据的编码是 UTF8的
在UNICODE编码下:将UTF8转换成Unicode即可
在多字节编码下:将UTF8转换为ASCII码即可
问题3 对返回数据的处理
=> 处理Json数据(解析Json数据)
引入一个Json开源的库 在Git上搜索Json就可以找到了 下载之
1.8.4 这是我下载的版本
在文件夹 makefiles -> msvc2010 -> jsoncpp.sln 一波操作
编译生成一个 lib_json.lib (不同版本可能会有差异,反正就会生成一个lib文件)
带上lib文件 和 include目录下的 json文件夹
在需要用到Json的工程下 包含这两个(lib文件 和 json文件夹)
然后引入:
包含:
VC++ 目录 -> 库目录 (说明:这个路径是lib的包含路径)
C/C++ -> 常规 -> 附加包含目录 (说明:这个路径是json文件夹 包含的路径,json文件夹中包含各种头文件)
链接器 -> 输入 -> 附加依赖项 加入 lib_json.lib (说明:就是你生成的lib的名字)
这样在工程中加入 #include "json.h"
就可以使用Json了
例子:
std::string strResult = "{\"data\":{\"yesterday\":{\"date\":\"27日 星期一\", \"temphigh\" : \"25\", \"wind\" : \"西风\"}},\"city\":\"长春\" }";
const char *str = strResult.c_str();
Json::CharReaderBuilder b;
Json::CharReader* reader(b.newCharReader());
Json::Value root;
JSONCPP_STRING errs;
bool ok = reader->parse(str, str + strlen(str), &root, &errs);
if (ok&&errs.size() == 0) // reader将Json字符串解析到root,root将包含Json里所有子元素
{
std::string CityName = root["city"].asString(); // 得到city = 长春
std::string code = root["data"]["yesterday"]["date"].asString(); // 得到 27日 星期一
cout << "CityName: " << CityName << endl;
cout << "code: " << code << endl;
}
delete reader; //这个是一定得要的 不然会内存泄漏
解析结果
CityName: 长春
code: 27日 星期一
demo:TestJsonData
遇到类似包含数组的情况 解决办法
例子:strResult : {“key1″:”value1″,”array”:[{"key2":"value2"},{"key2":"value3"},{"key2":"value4"}]}
这种情况怎么解析array
解决办法:
const char *str = strResult.c_str();
Json::CharReaderBuilder b;
Json::CharReader* reader(b.newCharReader());
Json::Value root;
JSONCPP_STRING errs;
bool ok = reader->parse(str, str + strlen(str), &root, &errs);
if (ok&&errs.size() == 0) // reader将Json字符串解析到root,root将包含Json里所有子元素
{
const Json::Value JsonArray = root["array"];
for (int i=0; i<array.size(); ++array)
{
string strKey2 = JsonArray[i]["Key2"].asString();
cout<<strKey2<<endl; //输出每个Key2的值
}
cout << "CityName: " << CityName << endl;
cout << "code: " << code << endl;
}
delete reader;
//解析Json中包含数组的格式
//参考:https://www.cnblogs.com/ytjjyy/archive/2012/04/17/2453348.html
=> 处理XML数据(解析XML)
在Git上找到TinyXML 下载之
工程tinyxml2 包含两个文件 tinyxml2.cpp 和 tinyxml2.h
可以批量编译 可选 32位和64位的DLL 或者 LIB进行编译
这里我选择的是lib 得到 tinyxml2.lib 这个文件
然后包含 tinyxml2.h 两个文件一起导入需要使用的工程中
导入方法同上
例子 有文件
<Class name="计算机软件班">
<Students>
<student name="张三" studentNo="13031001" sex="男" age="22">
<phone>88208888</phone>
<address>sssssss</address>
</student>
<student name="李四" studentNo="13031002" sex="男" age="20">
<phone>88206666</phone>
<address>2222222</address>
</student>
</Students>
</Class>
tinyxml2::XMLDocument *myDocument = new tinyxml2::XMLDocument();
myDocument->LoadFile("ssss.xml");
tinyxml2::XMLElement *rootElement = myDocument->RootElement(); //Class
tinyxml2::XMLElement *studentsElement = rootElement->FirstChildElement(); //Students
tinyxml2::XMLElement *studentElement = studentsElement->FirstChildElement(); //Student
while (studentElement)
{
const tinyxml2::XMLAttribute *attribute = studentElement->FirstAttribute(); //
while (attribute)
{
std::wstring strTemp = UTF8ToUnicode(attribute->Value());
std::string strName = UnicodeToANSI(strTemp);
std::cout << attribute->Name() << " : " << strName.c_str() << std::endl;
attribute = attribute->Next();
}
tinyxml2::XMLElement* phoneElement = studentElement->FirstChildElement();
std::cout << "phone" << " : " << phoneElement->GetText() << std::endl;
tinyxml2::XMLElement* addressElement = phoneElement->NextSiblingElement();
std::cout << "address" << " : " << phoneElement->GetText() << std::endl;
studentElement = studentElement->NextSiblingElement();
}
补充一些文本的转换方法
std::string UnicodeToUTF8(const std::wstring& str)
{
int iTextLen = WideCharToMultiByte(CP_UTF8, 0, str.c_str(), -1, NULL, 0, NULL, NULL);
char *pElementText = new char[iTextLen + 1];
memset((void*)pElementText, 0, sizeof(char) * (iTextLen + 1));
::WideCharToMultiByte(CP_UTF8, 0, str.c_str(), -1, pElementText, iTextLen, NULL, NULL);
std::string strText = pElementText;
delete[] pElementText;
return strText;
}
std::string UnicodeToANSI(const std::wstring& str)
{
char *pElementText;
int iTextLen = WideCharToMultiByte(CP_ACP, 0, str.c_str(), -1, NULL, 0, NULL, NULL);
pElementText = new char[iTextLen + 1];
memset((void*)pElementText, 0, sizeof(char) * (iTextLen + 1));
::WideCharToMultiByte(CP_ACP, 0, str.c_str(), -1, pElementText, iTextLen, NULL, NULL);
std::string strText;
strText = pElementText;
delete[] pElementText;
return strText;
}
std::wstring ANSIToUnicode(const std::string& str)
{
int unicodeLen = ::MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, NULL, 0);
wchar_t *pUnicode;
pUnicode = new wchar_t[unicodeLen + 1];
memset(pUnicode, 0, (unicodeLen + 1) * sizeof(wchar_t));
::MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, (LPWSTR)pUnicode, unicodeLen);
std::wstring rt;
rt = (wchar_t*)pUnicode;
delete pUnicode;
return rt;
}
std::wstring UTF8ToUnicode(const std::string& str)
{
int unicodeLen = ::MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, NULL, 0);
wchar_t *pUnicode = new wchar_t[unicodeLen + 1];
memset(pUnicode, 0, (unicodeLen + 1) * sizeof(wchar_t));
::MultiByteToWideChar(CP_UTF8,0,str.c_str(),-1,(LPWSTR)pUnicode,unicodeLen);
std::wstring rt = (wchar_t*)pUnicode;
delete pUnicode;
return rt;
}
到这里预备知识都已就绪 下面开始进入代码
核心代码:
GetWeatherDlg.h
// GetWeatherDlg.h: 头文件
//
#pragma once
#include <map>
#include <string>
#include <vector>
// CGetWeatherDlg 对话框
class CGetWeatherDlg : public CDialogEx
{
// 构造
public:
CGetWeatherDlg(CWnd* pParent = nullptr); // 标准构造函数
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_GETWEATHER_DIALOG };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
public:
void InitCityData();
std::string DelBlank(const std::string &str);
void ParseJsonData(std::string str);
void GetPageData(const CString &str);
void ShowResult();
void InitDateStruct();
void GetGb2312Data(const CString &str);
// 实现
protected:
HICON m_hIcon;
// 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnClickedBtnExit();
virtual BOOL PreTranslateMessage(MSG* pMsg);
afx_msg void OnBnClickedBtnSearch();
std::wstring StringToWString(const std::string & str);
std::wstring UTF8ToUnicode(const std::string& str);
private:
std::map<std::string,std::string>m_mapCity;
typedef struct Struct
{
CString CityName;
CString LifeSuggestion;
CString CurrentTemp;
std::vector<CString> vctDate;
std::vector<CString> TempHight;
std::vector<CString> Templow;
std::vector<CString> Wind;
std::vector<CString> Weather;
}WeatherData;
WeatherData m_WeatherData;
public:
CButton m_SearchBtn;
//afx_msg void OnEnChangeEditShowresult();
};
GetWeatherDlg.cpp
// GetWeatherDlg.cpp: 实现文件
//
#include "stdafx.h"
#include "GetWeather.h"
#include "GetWeatherDlg.h"
#include "afxdialogex.h"
#include <afxinet.h>
#include <string>
#include "json.h"
#include <iostream>
#include <fstream>
#include "MyIconv.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#ifndef ICONV_CONST
# define ICONV_CONST const
#endif
// CGetWeatherDlg 对话框
void GetIp02();
std::wstring ANSIToUnicode(const std::string& str)
{
int len = str.length();
int unicodeLen = ::MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, NULL, 0);
wchar_t *pUnicode;
pUnicode = new wchar_t[unicodeLen + 1];
memset(pUnicode, 0, (unicodeLen + 1) * sizeof(wchar_t));
::MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, (LPWSTR)pUnicode, unicodeLen);
std::wstring rt;
rt = (wchar_t*)pUnicode;
delete pUnicode;
return rt;
}
//GB2312到UTF-8的转换
std::string GB2312ToUTF8(const std::string strGb2312)
{
int len = MultiByteToWideChar(CP_ACP, 0, strGb2312.c_str(), -1, NULL, 0);
wchar_t* wstr = new wchar_t[len + 1];
memset(wstr, 0, len + 1);
MultiByteToWideChar(CP_ACP, 0, strGb2312.c_str(), -1, wstr, len);
len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
char* str = new char[len + 1];
memset(str, 0, len + 1);
WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, len, NULL, NULL);
if (wstr) delete[] wstr;
return str;
}
CGetWeatherDlg::CGetWeatherDlg(CWnd* pParent /*=nullptr*/)
: CDialogEx(IDD_GETWEATHER_DIALOG, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CGetWeatherDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_BTN_SEARCH, m_SearchBtn);
}
void CGetWeatherDlg::InitCityData()
{
m_mapCity.swap(std::map<std::string, std::string>());
//读取数据
std::ifstream in("CityName.dat");
if (!in.is_open())
{
//cout << "Error opening file";
//LOG(ERROR) << "Error opening file";
AfxMessageBox(L"配置文件不存在");
return;
}
std::string strCityCode = "";
std::string strCityName = "";
//map<string, string> mapcity;
//LOG(INFO) << "数据开始处理";
while (!in.eof())
{
char buffer[128] = { 0 };
in.getline(buffer, 128);
std::string strTemp = buffer;
int pos = strTemp.find(',');
strCityCode = strTemp.substr(0, pos);
strCityName = strTemp.substr(pos+1);
m_mapCity.insert(std::pair<std::string,std::string>(strCityCode, strCityName));
}
//LOG(INFO) << "数据处理完成";
}
std::string CGetWeatherDlg::DelBlank(const std::string & str)
{
std::string strSource = str;
int pos = strSource.find(' ');
strSource = strSource.substr(0, pos);
return strSource;
}
void CGetWeatherDlg::ParseJsonData(std::string str)
{
//对结构体中的数据进行处理
InitDateStruct();
//使用Json来解析得到的数据
Json::CharReaderBuilder b;
Json::CharReader* reader(b.newCharReader());
Json::Value JsonValue;
JSONCPP_STRING errs;
reader->parse(&str[0], &str[str.length()], &JsonValue, &errs);
//城市名
std::string cityname = JsonValue["data"]["city"].asString();
m_WeatherData.CityName = UTF8ToUnicode(cityname).c_str();
//生活建议
std::string suggestion = JsonValue["data"]["life"].asString();
m_WeatherData.LifeSuggestion = UTF8ToUnicode(suggestion).c_str();
//体感温度
std::string currenttemp = JsonValue["data"]["temp"].asString();
m_WeatherData.CurrentTemp = UTF8ToUnicode(currenttemp).c_str();
//未来几天的天气 日期 + 温度 + 天气 + 风向
const Json::Value arrayobj = JsonValue["data"]["forecast"]; //取一个数组中的数据
for (size_t i = 0; i < arrayobj.size(); ++i)
{
std::string strDate = arrayobj[i]["date"].asString();
m_WeatherData.vctDate.push_back(UTF8ToUnicode(strDate).c_str());
std::string strtemphigh = arrayobj[i]["temphigh"].asString();
m_WeatherData.TempHight.push_back(UTF8ToUnicode(strtemphigh).c_str());
std::string strtemplow = arrayobj[i]["templow"].asString();
m_WeatherData.Templow.push_back(UTF8ToUnicode(strtemplow).c_str());
std::string strWind = arrayobj[i]["wind"].asString();
m_WeatherData.Wind.push_back(UTF8ToUnicode(strWind).c_str());
std::string strWeather = arrayobj[i]["weather"].asString();
m_WeatherData.Weather.push_back(UTF8ToUnicode(strWeather).c_str());
}
delete reader; //需要释放掉 否则会内存泄漏
}
BEGIN_MESSAGE_MAP(CGetWeatherDlg, CDialogEx)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BTN_EXIT, &CGetWeatherDlg::OnBnClickedBtnExit)
ON_BN_CLICKED(IDC_BTN_SEARCH, &CGetWeatherDlg::OnBnClickedBtnSearch)
END_MESSAGE_MAP()
// CGetWeatherDlg 消息处理程序
BOOL CGetWeatherDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
InitCityData();
GetDlgItem(IDC_EDIT_CITYNAME)->SetWindowTextW(L"深圳");
(CEdit *)GetDlgItem(IDC_EDIT_CITYNAME)->SetFocus();
return FALSE;
//return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void CGetWeatherDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// 使图标在工作区矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
}
//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CGetWeatherDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CGetWeatherDlg::OnBnClickedBtnExit()
{
//TODO: 在此添加控件通知处理程序代码
InitDateStruct();
OnCancel();
}
BOOL CGetWeatherDlg::PreTranslateMessage(MSG* pMsg)
{
// TODO: 在此添加专用代码和/或调用基类
if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE)
return FALSE;
if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN) //和点击查询按钮绑定在一起 就简单的实现了点击回车键 就查询的功能
{
//AfxMessageBox(L"你点击了回车键");
OnBnClickedBtnSearch(); //点击Enter进行查询
return FALSE;
}
return CDialogEx::PreTranslateMessage(pMsg);
}
//通过输入的城市名称 来进行查询
void CGetWeatherDlg::OnBnClickedBtnSearch()
{
m_SearchBtn.EnableWindow(FALSE);
CString CityName = L"";
GetDlgItem(IDC_EDIT_CITYNAME)->GetWindowText(CityName);
if (CityName.IsEmpty())
{
AfxMessageBox(L"输入为空,请输入城市编码");
(CButton*)GetDlgItem(IDC_BTN_SEARCH)->EnableWindow(TRUE);
return;
}
USES_CONVERSION;
std::string CityNamestr = W2A(CityName);
std::string strCityId = "";
for (auto ptr : m_mapCity)
{
std::string strCity = DelBlank(ptr.second);
if (CityNamestr == strCity)
{
strCityId = ptr.first;
}
}
if (strCityId == "")
{
AfxMessageBox(L"输入的城市不存在,请重新输入");
CEdit *ptr = (CEdit*)GetDlgItem(IDC_EDIT_CITYNAME);
ptr->SetWindowText(L"");
ptr->Invalidate(TRUE);
return;
}
std::wstring wcitycode = StringToWString(strCityId);
GetPageData(wcitycode.c_str()); //获取数据为UTF8的数据
//Debug …… 测试获取到的GB2312数据如何处理
//GetGb2312Data(wcitycode.c_str());
//Debug 测试结果 获取网页数据可能有误 无法转换成正确的编码方式 显示结果
}
//将UTF8的数据转换为Unicode
std::wstring CGetWeatherDlg::UTF8ToUnicode(const std::string& str)
{
int len = str.length();
int unicodeLen = ::MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, NULL, 0);
wchar_t *pUnicode;
pUnicode = new wchar_t[unicodeLen + 1];
memset(pUnicode, 0, (unicodeLen + 1) * sizeof(wchar_t));
::MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, (LPWSTR)pUnicode, unicodeLen);
std::wstring rt;
rt = (wchar_t*)pUnicode;
delete pUnicode;
return rt;
}
//将Unicode转换成ASCII
std::string UnicodeToANSI(const std::wstring& str)
{
char *pElementText;
int iTextLen = WideCharToMultiByte(CP_ACP, 0, str.c_str(), -1, NULL, 0, NULL, NULL);
pElementText = new char[iTextLen + 1];
memset((void*)pElementText, 0, sizeof(char) * (iTextLen + 1));
::WideCharToMultiByte(CP_ACP, 0, str.c_str(), -1, pElementText, iTextLen, NULL, NULL);
std::string strText;
strText = pElementText;
delete[] pElementText;
return strText;
}
//得到UTF8的数据
void CGetWeatherDlg::GetPageData(const CString &strUrl)
{
CString url = L"http://api.help.bj.cn/apis/weather6d/?id="; //返回值 可以使用
url += strUrl;
CInternetSession session;
CHttpFile* pFile = (CHttpFile*)session.OpenURL(url);
DWORD dwStatusCode;
pFile->QueryInfoStatusCode(dwStatusCode);
CString Getstring = L"";
if (dwStatusCode == HTTP_STATUS_OK)
{
CString strTemp = L"";
while (pFile->ReadString(strTemp))
{
Getstring += strTemp;
}
}
session.Close();
pFile->Close();
delete pFile; //这个必须得有 否则会导致内存泄漏
std::string strtemp = (const char *)Getstring.GetString();
ParseJsonData(strtemp); //解析数据
ShowResult();
}
void CGetWeatherDlg::GetGb2312Data(const CString &str)
{
m_SearchBtn.EnableWindow();
CString url = L"http://wthrcdn.etouch.cn/weather_mini?citykey="; //返回值
url += str;
CInternetSession session;
CHttpFile* pFile = (CHttpFile*)session.OpenURL(url);
DWORD dwStatusCode;
pFile->QueryInfoStatusCode(dwStatusCode);
CString Getstring = L"";
if (dwStatusCode == HTTP_STATUS_OK)
{
CString strTemp = L"";
while (pFile->ReadString(strTemp))
{
Getstring += strTemp;
}
}
int length = Getstring.GetLength();
std::wstring WGetString = Getstring;
session.Close();
pFile->Close();
delete pFile; //这个必须得有 否则会导致内存泄漏
std::string strSource = (const char *)WGetString.c_str();
//char out[1024] = { 0 };
//char *charSource = (char*)strSource.c_str();
gb2312-->utf-8
//CodeConverter cc2 = CodeConverter("gb2312", "utf-8");
//cc2.convert((char *)WGetString.c_str(), length, out, 1024);
//debug*************开始*****************测试使用转换方法 不行
//std::string strOut = GB2312ToUTF8(strSource);
//std::wstring strShow = UTF8ToUnicode(strOut);
//AfxMessageBox(strShow.c_str());
//debug*************结束********************
//WGetString
AfxMessageBox(WGetString.c_str());
}
void CGetWeatherDlg::InitDateStruct()
{
m_WeatherData.CityName = L"";
m_WeatherData.LifeSuggestion = L"";
m_WeatherData.CurrentTemp = L"";
m_WeatherData.vctDate.swap(std::vector<CString>());
m_WeatherData.TempHight.swap(std::vector<CString>());
m_WeatherData.Templow.swap(std::vector<CString>());
m_WeatherData.Wind.swap(std::vector<CString>());
m_WeatherData.Weather.swap(std::vector<CString>());
}
std::wstring CGetWeatherDlg::StringToWString(const std::string & str)
{
int num = MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, NULL, 0);
wchar_t *wide = new wchar_t[num];
MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, wide, num);
std::wstring w_str(wide);
delete[] wide;
return w_str;
}
void CGetWeatherDlg::ShowResult()
{
//获取当前的时间段
time_t t = time(0);
char temp[64];
std::string strYearMonth;
tm *Time = localtime(&t);
strftime(temp, sizeof(temp), "%Y年%m月", Time); //格式化时间输出 %Y-%m-%d %H:%M:%S
strYearMonth = temp;
std::wstring DateHead = StringToWString(strYearMonth);
/*
显示格式:
城市:
日期
天气
气温
风向
体感温度
建议
*/
CString strShowResult = L"";
strShowResult += m_WeatherData.CityName;
strShowResult += L"\r\n";
strShowResult += DateHead.c_str() + m_WeatherData.vctDate[0];
strShowResult += L"\r\n";
strShowResult += L"天气: " + m_WeatherData.Weather[0];
strShowResult += L"\r\n";
strShowResult += L"最高温度: " + m_WeatherData.TempHight[0];
strShowResult += L"℃";
strShowResult += L"\r\n";
strShowResult += L"最低温度: " + m_WeatherData.Templow[0];
strShowResult += L"℃";
strShowResult += L"\r\n";
strShowResult += L"风向: " + m_WeatherData.Wind[0];
strShowResult += L"\r\n";
strShowResult += L"当前温度: " + m_WeatherData.CurrentTemp;
strShowResult += L"℃";
strShowResult += L"\r\n";
strShowResult += L"建议: " + m_WeatherData.LifeSuggestion;
CEdit *ptr = (CEdit*)GetDlgItem(IDC_EDIT_ShowResult);
ptr->SetWindowTextW(strShowResult);
m_SearchBtn.EnableWindow();
}
//得到简体中文 GB2312 这里需要转换为Unicode
void GetIp02()
{
//CString url = L"http://wthrcdn.etouch.cn/weather_mini?citykey=101010100"; //得到简体中文 GB2312 所以需要转换为Unicode进行显示
//CString url = L"http://ip.dnsexit.com/"; //61.144.174.130
CString url = L"http://wthrcdn.etouch.cn/WeatherApi?citykey=101010100"; //XML文件
CInternetSession session(L"Microsoft Internet Browser");
CHttpFile* pFile = (CHttpFile*)session.OpenURL(url);
DWORD dwStatusCode;
pFile->QueryInfoStatusCode(dwStatusCode);
CString content;
//std::string GetString = "";
std::wstring GetString = L"";
//std::wstring GetString = L"";
if (dwStatusCode == HTTP_STATUS_OK)
{
//CString strTemp = L"";
//while (pFile->ReadString(strTemp))
// content += strTemp;
wchar_t strBuff[512] = { 0 };
while (pFile->Read((void*)strBuff, 512))
{
GetString += strBuff;
}
}
session.Close();
pFile->Close();
delete pFile; //这个必须得有 否则会导致内存泄漏
//size_t length = content.GetLength();
//AfxMessageBox(content);
//std::wstring wstrResult = GB2312ToUnicode((const char*)content.GetString()); //GB2312转换成Unicode 进行显示
//std::wstring wstrResult = UTF8ToUnicode((const char*)content.GetString()); //GB2312转换成Unicode 进行显示
//std::wstring wstrResult = UTF8ToUnicode(GetString);
//std::string stringResult = UnicodeToANSI(wstrResult);
CFile file;
bool success = file.Open(L"Test.txt", CFile::modeWrite | CFile::modeCreate);
if (!success)
{
AfxMessageBox(_T("文件创建有误……"));
return;
}
file.Write(GetString.c_str(), GetString.length());
file.Close();
AfxMessageBox(L"保存数据结束");
//AfxMessageBox(wstrResult.c_str());
}
最后运行效果如下:
最后带上整个工程的百度云地址:
链接:https://pan.baidu.com/s/1AkdWcYJOKlsflyouwBk4RA
提取码:al87