C++获取天气信息

无论是获取网络上的天气信息或者其它的信息,首先要做的,就是访问对方的服务器,向服务器发送请求,然后接收数据。

这里也是一样的,也是向服务器发送一个GET请求,然后接收数据,对数据进行处理,然后保存到文件中,weather.txt即为处理后的文件

其中,有一些函数,如:socket(),connect(),send(),recv()之类,这些属于C语言的socket编程,找孙鑫老师的视频一集就能学会。

话说,手动处理这些东西是很麻烦的,如果有时间的小伙伴可以自己封装一个类就行,使用其它网络上有的库来处理也行。
这里是为了让小伙伴们了解整个过程 ,所以手动处理了。

其它,下面还有6个<li>...</li>,这里包含的就是后面六天的天气情况,并没有处理,只处理了当天的,但方法是一样的
有兴趣的小伙伴可以 自己去试试 ,毕竟大神之路是需要自己走的,哈哈。

希望小伙伴们能举一反三,让我的这块砖头引出古玉……

下面是处理后的信息


代码如下:
环境:VS2013 + Win7
  1. #define _WINSOCK_DEPRECATED_NO_WARNINGS
  2. #define _CRT_SECURE_NO_WARNINGS
  3. #include <WinSock2.h>
  4. #include <iostream>
  5. #include <stdio.h>
  6. #include <string>

  7. #pragma comment(lib, "ws2_32")

  8. using namespace std;

  9. /* 用于取得错误信息 */
  10. DWORD g_dwErr;

  11. /* 保存数组的大小 */
  12. const int MAX_SIZE = 40960;

  13. /*
  14.         此结构体用于保存天气信息
  15. */
  16. typedef struct stWeatherInfo
  17. {
  18.         string date;        //日期
  19.         string wea;                //天气
  20.         string tem;                //温度
  21.         string win;                //风力
  22. }WeatherInfo, *pWeatherInfo;

  23. /* 用于处理THML中的数据,把相应信息放入结构体中 */
  24. void GetWeather(const string& s);

  25. int main()
  26. {
  27.         /* 初始化 */
  28.         WSADATA wsdata;
  29.         WSAStartup(MAKEWORD(2, 2), &wsdata);

  30.         const char* hostname = "www.weather.com.cn";
  31.         struct hostent* host = gethostbyname(hostname);

  32.         /* 初始化一个连接服务器的结构体 */
  33.         sockaddr_in serveraddr;
  34.         serveraddr.sin_family = AF_INET;
  35.         serveraddr.sin_port = htons(80);

  36.         /* 此处也可以不用这么做,不需要用gethostbyname,把网址ping一下,得出IP也是可以的 */
  37.         serveraddr.sin_addr.S_un.S_addr = *((int*)*host->h_addr_list);

  38.         int sock = socket(AF_INET, SOCK_STREAM, 0);
  39.         if (sock == -1) {
  40.                 cout << "socket error" << endl;
  41.                 return -1;
  42.         }
  43.         cout << "socket succeed" << endl;

  44.         if (connect(sock, (struct sockaddr*)&serveraddr, sizeof(sockaddr_in)) == -1) {
  45.                 g_dwErr = GetLastError();
  46.                 cout << "connect error" << endl;
  47.                 closesocket(sock);
  48.                 return -1;
  49.         }
  50.         cout << "connect succeed" << endl;

  51.         /* GET请求 */
  52.         const char* bufSned = "GET http://www.weather.com.cn/weather/101280601.shtml\r\n";

  53.         /* 发送GET请求 */
  54.         if (send(sock, bufSned, strlen(bufSned), 0) > 0) {
  55.                 cout << "send succeed" << endl;
  56.         } else {
  57.                 g_dwErr = GetLastError();
  58.                 cout << "send error, 错误编号: "<< g_dwErr << endl;
  59.                 closesocket(sock);
  60.                 return -1;
  61.         }

  62.         /* 文件,用于把HTML源码保存起来,没什么用处,只是为了自己看一下源码而已 */
  63.         FILE *fp;
  64.         fp = fopen("get.txt","w");

  65.         char BufRecv[MAX_SIZE] = {};
  66.         int nLen = 0;
  67.         string HtmlData;

  68.         /* 开始接收数据 */
  69.         while ((nLen = recv(sock, BufRecv, MAX_SIZE, 0)) > 0) {

  70.                 /* 写文件 */
  71.                 fwrite(BufRecv, 1, nLen, fp);

  72.                 /* 把数组拼接成string类型,方便下面的处理 */
  73.                 HtmlData += BufRecv;
  74.         }

  75.         /* 开始分析HTML */
  76.         string Area0 = "<ul class=\"t clearfix\">";
  77.         string Area1 = "<li class=\'on\'>";
  78.         string Area2 = "</li>";

  79.         string::size_type PosBegin0;
  80.         string::size_type PosBegin;
  81.         string::size_type PosEnd;
  82.         string s;
  83.         PosBegin0 = HtmlData.find(Area0);
  84.         if (PosBegin0 > 0) {
  85.                 PosBegin = HtmlData.find(Area1, PosBegin0);
  86.                 PosEnd = HtmlData.find(Area2, PosBegin);
  87.                 s = HtmlData.substr(PosBegin, PosEnd - PosBegin + 5);
  88.                 //cout << s << endl;                //s即为存储天气信息的HTML源码
  89.         }
  90.         /* 结束HTML分析 */

  91.         /* 处理存储有天气部分的HTML代码 */
  92.         GetWeather(s);

  93.         fclose(fp);
  94.         cin.get();
  95.         closesocket(sock);
  96.         return 0;
  97. }

  98. void GetWeather(const string& s)
  99. {
  100.         WeatherInfo weatherinfo;
  101.         string::size_type DataPosBegin = s.find("<h1>");
  102.         string::size_type DataPosEnd = s.find("</h1>");
  103.         weatherinfo.date = s.substr(DataPosBegin + 4, DataPosEnd - DataPosBegin - 4);

  104.         string::size_type WeaPosEnd = s.find("</p>");
  105.         string::size_type WeaPosBegin = s.rfind(">", WeaPosEnd);
  106.         weatherinfo.wea = s.substr(WeaPosBegin + 1, WeaPosEnd - WeaPosBegin - 1);

  107.         string::size_type TemPosBegin1 = s.find("<span>");
  108.         string::size_type TemPosEnd1 = s.find("</span>");
  109.         string tem1 = s.substr(TemPosBegin1 + 6, TemPosEnd1 - TemPosBegin1 - 6);

  110.         string::size_type TemPosBegin2 = s.find("<i>");
  111.         string::size_type TemPosEnd2 = s.find("</i>", TemPosBegin2);
  112.         string tem2 = s.substr(TemPosBegin2 + 3, TemPosEnd2 - TemPosBegin2 - 3);
  113.         weatherinfo.tem = tem1 + "/" + tem2;

  114.         string::size_type WinPosBegin = s.find("</em>");
  115.         WinPosBegin = s.find("<i>", WinPosBegin);
  116.         string::size_type WinPosEnd = s.find("</i>", WinPosBegin);
  117.         weatherinfo.win = s.substr(WinPosBegin + 3, WinPosEnd - WinPosBegin - 3);

  118.         /*
  119.         cout << "日期:" << weatherinfo.date << endl;
  120.         cout << "天气:" << weatherinfo.wea << endl;
  121.         cout << "温度:" << weatherinfo.tem << endl;
  122.         cout << "风力:" << weatherinfo.win << endl;
  123.         */

  124.         /* 把获取的天气信息写入到文件中 */
  125.         FILE *fp;
  126.         fp = fopen("weather.txt","w");
  127.         fwrite(weatherinfo.date.c_str(), 1, weatherinfo.date.length(), fp);
  128.         fwrite(weatherinfo.wea.c_str(), 1, weatherinfo.wea.length(), fp);
  129.         fwrite(weatherinfo.tem.c_str(), 1, weatherinfo.tem.length(), fp);
  130.         fwrite(weatherinfo.win.c_str(), 1, weatherinfo.win.length(), fp);

  131.         fclose(fp);
  132. }
  • 5
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
### 回答1: Qt界面通过网络获取天气信息的过程,一般可以分为以下几个步骤: 第一步,创建请求对象。使用Qt提供的QNetworkRequest类创建一个请求对象,设置请求的URL地址以及请求的Header信息。 第二步,发送请求。使用Qt的QNetworkAccessManager类发送上述请求对象,调用其get()函数即可发送请求。 第三步,接收相应。Qt的QNetworkAccessManager类会自动接收到服务器的相应信息,可以通过其finished()信号捕捉到这个事件,回调函数中则可以读取响应的信息。 第四步,解析数据。一般天气信息返回的是Json格式数据,我们需要使用Qt的Json解析器Qt Json来解析数据,将其转换成相应的数据结构,例如用QJsonObject表示城市名、温度、天气状况等信息。 第五步,更新UI。将第四步中解析得到的数据结构,通过Qt界面的QLabel、QTextBrowser等控件,动态地更新显示在界面上。 需要注意在整个网络获取天气信息的过程中,需要添加相应的错误处理,例如网络连接失败、天气数据解析出错等等情况,以保证界面能够及时地响应用户的操作。 ### 回答2: Qt界面是一种基于C++的图形用户界面开发框架。这种框架可以帮助开发者创建出漂亮、易于使用、跨平台的应用程序界面。Qt界面中内置了许多通信和网络相关的类库,使得开发者可以很方便地利用网络进行数据的获取和传输。 获取天气信息通常需要连接到一个天气服务的API,通过发送HTTP请求来获取数据,再将数据解析回传给应用程序进行处理。在Qt界面中,可以使用QNetworkAccessManager等相关类库来实现这个过程。具体而言,可以通过下列步骤来实现: 1. 创建一个QNetworkAccessManager对象,该对象可以用于发送HTTP请求和接收响应数据。 2. 构造HTTP请求对象。对于获取天气信息,通常需要指定一个特定的URL,以及HTTP请求头部的一些参数,例如浏览器类型、语言等。 3. 发送HTTP请求,并等待响应。当响应数据到达时,QNetworkAccessManager对象会发出相应的信号,用于通知应用程序已经得到响应数据。 4. 按照天气API返回的格式,解析响应数据,并提取所需要的信息。这部分工作需要根据具体API的规定进行实现。 5. 将解析获得的天气信息显示在Qt界面上。这一过程中,可以利用Qt的控件和布局等功能,将获取到的信息以适当的方式进行展示。 综上所述,Qt界面通过网络获取天气信息可以利用QNetworkAccessManager等类库,通过发送HTTP请求、解析响应数据实现。这种方法具有可靠性高、代码清晰等优点,可以满足大多数天气API的调用需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值