c++实现查询天气预报
用到的函数、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之间的转换(见这篇文章http://blog.csdn.net/lgh1992314/article/details/8579206)
5、Jsoncpp(主要是处理1中的数据==见这篇文章http://blog.csdn.net/lgh1992314/article/details/8582179)
...
程序依赖于数据库中的城市以及城市代码的丰富度,所以有的城市可能会查询不到哦。
半成品:
#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"}}
数据就这么多。
城市代码太长就不加在文章中了,请点击下载