用到的函数、API等
1、中央气象台API返回的JSON数据(http://m.weather.com.cn/data/101010100.html)
2、外网获取IP(http://ip.dnsexit.com/index.php)
3、Sqlite(1中的城市代号利用sqlite3实现查询)
4、C++中GB2312字符串和UTF-8之间的转换(见这篇文章)
5、Jsoncpp(主要是处理1中的数据==见这篇文章)
...
程序依赖于数据库中的城市以及城市代码的丰富度,所以有的城市可能会查询不到哦。
半成品:
#include <iostream>
#include <ctime>
#include <string>
#include <cstring>
#include <cstdlib>
#include <sstream>
#include <fstream>
#include <sqlite3.h>
#include <afxinet.h>
#include <windows.h>
#include<json.h>
#pragma comment(lib,"sqlite3.lib")
using namespace Json;
using namespace std;
std::string City_code;
int sqlite3_exec_callback(void *data, int n_columns, char **col_values, char **col_names)
{
//int i;
/*for(i=0; i < n_columns; i++)
{
cout << col_values[i] << "\t";
}
cout << endl;*/
City_code = col_values[0];
return 0;
}
std::string UtfToGb(std::string utf8)//UTF-8 to GB2312
{
int len = MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), -1, NULL, 0);
wchar_t* wstr = new wchar_t[len+1];
memset(wstr, 0, len+1);
MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), -1, wstr, len);
len = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL);
char* str = new char[len+1];
memset(str, 0, len+1);
WideCharToMultiByte(CP_ACP, 0, wstr, -1, str, len, NULL, NULL);
if(wstr) delete[] wstr;
std::string strs = (str);
delete []str;
return strs;
}
void jsonDate(string strValue) //Jsoncpp
{
//Json::StyledWriter style_write;
Json::Value value;
Json::Reader reader;
reader.parse(strValue, value);
//std::cout << style_write.write(value) << std::endl;
std::cout << value["weatherinfo"]["date_y"].asString() << " ";
std::cout << value["weatherinfo"]["week"].asString() << std::endl;
std::cout << "================================================" << std::endl;
std::cout << "= " << value["weatherinfo"]["temp1"].asString() << " " << " "
<< value["weatherinfo"]["weather1"].asString() << value["weatherinfo"]["wind1"].asString() << std::endl;
std::cout << "= " << value["weatherinfo"]["temp2"].asString() << " "
<< value["weatherinfo"]["weather2"].asString() << " " << value["weatherinfo"]["wind2"].asString() << std::endl;
std::cout << "= " << value["weatherinfo"]["temp3"].asString() << " "
<< value["weatherinfo"]["weather3"].asString() << " " << value["weatherinfo"]["wind3"].asString() << std::endl;
std::cout << "= " << value["weatherinfo"]["temp4"].asString() << " "
<< value["weatherinfo"]["weather4"].asString() << " " << value["weatherinfo"]["wind4"].asString() << std::endl;
std::cout << "= " << value["weatherinfo"]["temp5"].asString() << " "
<< value["weatherinfo"]["weather5"].asString() << " " << value["weatherinfo"]["wind5"].asString() << std::endl;
std::cout << "= " << value["weatherinfo"]["temp6"].asString() << " "
<< value["weatherinfo"]["weather6"].asString() << " " << value["weatherinfo"]["wind6"].asString() << std::endl;
std::cout << "================================================" << std::endl;
}
std::string GetIp()
{
CString url = "http://ip.dnsexit.com/";
CString content;
CString data;
DWORD dwStatusCode;
CInternetSession session("HttpClient");
CHttpFile* pfile = (CHttpFile *)session.OpenURL(url);
pfile -> QueryInfoStatusCode(dwStatusCode);
if(dwStatusCode == HTTP_STATUS_OK)
{
while (pfile -> ReadString(data))
{
content += data;
}
}
pfile -> Close();
delete pfile;
session.Close();
return std::string(content);
}
std::string GetProvince(std::string ip)
{
std::string url = "http://www.youdao.com/smartresult-xml/search.s?type=ip&q=";
url.append(ip);
CString content;
CString data;
DWORD dwStatusCode;
CInternetSession session("HttpClient");
CHttpFile* pfile = (CHttpFile *)session.OpenURL(url.c_str());
pfile -> QueryInfoStatusCode(dwStatusCode);
if(dwStatusCode == HTTP_STATUS_OK)
{
while (pfile -> ReadString(data))
{
content += data;
}
}
pfile -> Close();
delete pfile;
session.Close();
std::string result = std::string(content);
int left = result.find("<location>");
int right = result.find("</location>");
//cout << left << "\t" << right << endl;
std::string province = result.substr(left + 10,right - left - 10 - 5);
return province;
}
std::string GetWeather(std::string city_code)
{
std::string url = "http://m.weather.com.cn/data/";
url.append(city_code);
url.append(".html");
CString content;
CString data;
DWORD dwStatusCode;
CInternetSession session("HttpClient");
CHttpFile* pfile = (CHttpFile *)session.OpenURL(url.c_str());
pfile -> QueryInfoStatusCode(dwStatusCode);
if(dwStatusCode == HTTP_STATUS_OK)
{
while (pfile -> ReadString(data))
{
content += data;
}
}
pfile -> Close();
delete pfile;
session.Close();
return UtfToGb(std::string(content));
}
void ShowWeather()
{
sqlite3 *db = NULL;
char *err_msg = NULL;
if(SQLITE_OK != sqlite3_open("weather.db",&db))
{
std::cout << "can't open the database." << std::endl;
exit(-1);
}
std::string province;
std::string ip = GetIp();
std::cout << "IP:" << ip << std::endl;
province = GetProvince(ip);
std::cout << "您所在的地方:" << province << std::endl;
std::cout << "您所在地天气:" << std::endl;
std::string city = province.substr(province.find("省") + 2,4);
std::string sql = "select city_code from weather where city = ";
sql.append("\"");
sql.append(city);
sql.append("\"");
sqlite3_exec(db, sql.c_str(), &sqlite3_exec_callback, 0, &err_msg);
string strValue = GetWeather(City_code);
jsonDate(strValue);
City_code.clear();
sqlite3_close(db);
}
int main()
{
ShowWeather();
sqlite3 *db = NULL;
char *err_msg = NULL;
if(SQLITE_OK != sqlite3_open("weather.db",&db))
{
std::cout << "can't open the database." << std::endl;
exit(-1);
}
std::string province;
std::string sql = "select city_code from weather where city = ";
std::cout << "please input the province" << std::endl;
std::cin >> province;
sql.append("\"");
sql.append(province);
sql.append("\"");
std::cout << "天气:" << std::endl;
sqlite3_exec(db, sql.c_str(), &sqlite3_exec_callback, 0, &err_msg);
string strValue = GetWeather(City_code);
jsonDate(strValue);
sqlite3_close(db);
return 0;
}
输出:
IP:124.135.247.252
您所在的地方:山东省聊城市
您所在地天气:
2013年2月16日 星期六
================================================
= 7℃~0℃ 多云转雨夹雪南风3-4级转小于3级
= 4℃~-3℃ 阴转小雪 南风小于3级转北风4-5级
= 1℃~-7℃ 阴转多云 北风3-4级转小于3级
= 3℃~-4℃ 晴 南风小于3级
= 5℃~-4℃ 晴 北风小于3级
= 7℃~-2℃ 晴 南风小于3级
================================================
please input the province
北京
天气:
2013年2月16日 星期六
================================================
= 2℃~-3℃ 阴转多云微风
= 6℃~-4℃ 多云转晴 北风3-4级
= 3℃~-8℃ 晴 北风3-4级转微风
= 3℃~-6℃ 晴 微风
= 4℃~-6℃ 晴转多云 微风
= 4℃~-5℃ 多云转晴 微风
================================================
请按任意键继续. . .
国家气象局提供的天气预报接口主要有三个,分别是:
http://www.weather.com.cn/data/sk/101010100.html
http://www.weather.com.cn/data/cityinfo/101010100.html
http://m.weather.com.cn/data/101010100.html
其中详细接口为:http://m.weather.com.cn/data/101010100.html
以下是http://m.weather.com.cn/data/101010100.html接口json格式提供,格式如下
{"weatherinfo":{
//基本信息
//fchh是系统更新时间
"city":"北京","city_en":"beijing","date_y":"2011年10月23 日","date":"辛卯年","week":"星期 日","fchh":"11","cityid":"101010100",
//6天内的温度
"temp1":"16℃~6℃","temp2":"16℃~3℃","temp3":"16℃~6℃","temp4":"14℃~6℃",
"temp5":"17℃~5℃","temp6":"18℃~8℃",
//6天内华氏度
"tempF1":"60.8℉~42.8℉","tempF2":"60.8℉~37.4℉","tempF3":"60.8℉~42.8℉",
"tempF4":"57.2℉~42.8℉","tempF5":"62.6℉~41℉","tempF6":"64.4℉~46.4℉",
//每日天气变化
"weather1":" 小雨转晴","weather2":"晴","weather3":"晴转阴","weather4":"多云转阴","weather5":"阴转 晴","weather6":"晴转多 云",
//天气描述(图片序号)
"img1":"7","img2":"0","img3":"0","img4":"99","img5":"0","img6":"2","img7":"1",
"img8":"2","img9":"2","img10":"0","img11":"0","img12":"1","img_single":"7",
//天气描述(文字描述)
"img_title1":" 小雨","img_title2":"晴","img_title3":"晴","img_title4":"晴","img_title5":" 晴",
"img_title6":"阴","img_title7":"多云","img_title8":"阴","img_title9":" 阴","img_title10":"晴",
"img_title11":"晴","img_title12":"多 云","img_title_single":"小雨",
//风向描述
"wind1":"北风4-5级","wind2":"北风3-4级转微 风","wind3":"微风","wind4":"微风","wind5":"微风",
"wind6":"微风","fx1":"北 风","fx2":"北风",
//风力描述
"fl1":"4-5级","fl2":"3-4级转小于3级","fl3":"小于3级","fl4":"小于3 级","fl5":"小于3级","fl6":"小于3级",
//今天穿衣指数
"index":"温凉","index_d":"较凉爽,建议着夹衣加薄羊毛衫等春秋服 装。体弱者宜着夹衣加羊毛衫。因昼夜温差较大,注意增减衣服。",
//48小时内穿衣指数
"index48":"温凉","index48_d":"较凉爽,建议着夹衣加薄羊毛 衫等春秋服装。体弱者宜着夹衣加羊毛衫。因昼夜温差较大,注意增减衣服。",
//紫外线
"index_uv":"最弱","index48_uv":"中 等",
//洗车
"index_xc":"不宜",
//旅游
"index_tr":"适宜",
//人体舒适度
"index_co":"较舒 适",
//未知
"st1":"14","st2":"3","st3":"14","st4":"5","st5":"15","st6":"5",
//晨练
"index_cl":" 较不宜",
//晾衣
"index_ls":"不宜",
//过敏
"index_ag":"极不易发"}}
当天基础天气接口
http://www.weather.com.cn/data/cityinfo/101010100.html
以下是http://www.weather.com.cn/data/cityinfo/101010100.html接口提供是Json格式提供,数据如下:
//ptime为系统最后更新时间
{"weatherinfo":{"city":"北 京","cityid":"101010100","temp1":"16℃","temp2":"6℃","weather":"小雨转 晴","img1":"d7.gif","img2":"n0.gif","ptime":"11:00"}}
当天基础天气接口
http://www.weather.com.cn/data/sk/101010100.html
以下是http://www.weather.com.cn/data/sk/101010100.html接口提供是Json格式提供,数据如下:
//temp为摄氏度
//isRadar 应该是雷达返回成功标识
//Radar是雷达编号
//time是该数据更新时间
{"weatherinfo":{"city":"北京","cityid":"101010100","temp":"10","WD":"东北 风","WS":"4 级","SD":"56%","WSE":"4","time":"16:40","isRadar":"1","Radar":"JC_RADAR_AZ9010_JB"}}
数据就这么多。
城市代码太长就不加在文章中了,请点击下载
Keep it simple!
作者:N3verL4nd