编写一个基于命令行的获取天气预报的程序。(云市场天气API、HTTP、JSON )

更多资料请点击:我的目录
本篇仅用于记录自己所学知识及应用,代码仍可优化,仅供参考,如果发现有错误的地方,尽管留言于我,谢谢。
快递信息查询

运行效果:
在这里插入图片描述

main函数:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
#include "cJSON.h"

char *httpRequest()
{
    
    
    static char request[1024];
    printf("请求获取信息!\n\n");
    snprintf(request, 1024, "GET /spot-to-weather?area=广州 HTTP/1.1\r\n"
                            "Host:weather01.market.alicloudapi.com\r\n"
                            "Authorization:APPCODE 8b75a704109c40089f49902b2fa745\r\n"
                            "\r\n");
    return request;
}

int main()
{
    
    
    struct hostent *he = gethostbyname("weather01.market.alicloudapi.com");
    if(he == NULL)
    {
    
    
        perror("DNS解析失败");
        exit(0);
    }
    printf("IP:%s\n", inet_ntoa(*((struct in_addr *)(he->h_addr_list)[0])));
    char buf[20] = {
    
    0};
    sprintf(buf,"%s",inet_ntoa(*((struct in_addr *)(he->h_addr_list)[0])));

    struct sockaddr_in bindaddr;                                                    //定义ipv4地址结构体变量
    bzero(&bindaddr,sizeof(bindaddr));
    bindaddr.sin_family=AF_INET;
    bindaddr.sin_addr.s_addr=inet_addr("192.168.1.157");                            //绑定客户端自己的ip地址
    bindaddr.sin_port=htons(10000);                                                 //绑定客户端自己的端口号

    struct sockaddr_in serveraddr;                                                  //定义结构体变量存放对方(服务器)的ip和端口号
    bzero(&serveraddr,sizeof(serveraddr));
    serveraddr.sin_family=AF_INET;
    serveraddr.sin_addr.s_addr=inet_addr(buf);                                      //服务器的ip地址
    serveraddr.sin_port=htons(80);                                                  //服务器的端口号

    int tcpsock=socket(AF_INET,SOCK_STREAM,0);                                      //创建tcp套接字
    if(tcpsock==-1)
    {
    
    
        perror("创建tcp套接字!\n");
        return -1;
    }

    int on=1;
    setsockopt(tcpsock,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));                     //设置端口释放后立即就可以被再次使用

    int ret=bind(tcpsock,(struct sockaddr *)&bindaddr,sizeof(bindaddr));            //绑定ip和端口号
    if(ret==-1)
    {
    
    
        perror("绑定失败!\n");
        return -1;
    }

    ret=connect(tcpsock,(struct sockaddr *)&serveraddr,sizeof(serveraddr));         //连接服务器
    if(ret==-1)
    {
    
    
        perror("连接服务器失败!\n");
        return -1;
    }
    else
    {
    
    
        printf("链接成功!\n");
    }

    char *s = httpRequest();
    write(tcpsock, s, strlen(s));

    // 接收服务器的 HTTP 响应
    char *response = calloc(100, 1024);
    int total = 0;
    while(1)
    {
    
    
        if(total > 100*1024)
        {
    
    
            printf("响应数据超过100k,请重新分配内存\n");
            break;
        }

        int n = read(tcpsock, response+total, 10*1024);
        if(n <= 0)
            break;

        total += n;
    }

    //printf("响应报文:%s", response);

    char *sbuf = calloc(100, 1024);
    strtok(response,"{");                                                           //以第一个大括号分割
    sprintf(sbuf,"{%s",strtok(NULL,"\0"));                                          //补回被分割的{
    
    
    //printf("JSON数据:%s", sbuf);                                                  //通过https://www.bejson.com/jsonviewernew/查看JSON视图

    cJSON* root = cJSON_Parse(sbuf);                                                //从给定的json字符串中得到cjson对象,(root即为根目录)
    cJSON* root_body = cJSON_GetObjectItem(root, "showapi_res_body");               //根据键获取对应的值(cjson对象),(root_body即为root的下一级目录)
    cJSON* root_body_city_info = cJSON_GetObjectItem(root_body, "cityInfo");        //根据键获取对应的值(cjson对象)
    cJSON* root_body_day1 = cJSON_GetObjectItem(root_body, "f1");                   //根据键获取对应的值(cjson对象),(root_body_day1即为root_body的下一级目录)

    printf("城市: %s\n",cJSON_GetObjectItem(root_body_city_info, "c5")->valuestring);

    cJSON* root_body_d1w1 = cJSON_GetObjectItem(root_body_day1, "day");
    printf("日期: %s\n",root_body_d1w1->valuestring);

    cJSON* root_body_d1w2 = cJSON_GetObjectItem(root_body_day1, "day_weather");
    printf("日间天气: %s\n",root_body_d1w2->valuestring);

    cJSON* root_body_d1w3 = cJSON_GetObjectItem(root_body_day1, "night_weather");
    printf("夜间天气: %s\n",root_body_d1w3->valuestring);

    cJSON* root_body_d1w4 = cJSON_GetObjectItem(root_body_day1, "day_air_temperature");
    printf("日间温度: %s\n",root_body_d1w4->valuestring);

    cJSON* root_body_d1w5 = cJSON_GetObjectItem(root_body_day1, "night_air_temperature");
    printf("夜间温度: %s\n\n",root_body_d1w5->valuestring);

    printf("城市: %s\n",cJSON_GetObjectItem(root_body_city_info, "c5")->valuestring);

    cJSON* root_body_day2 = cJSON_GetObjectItem(root_body, "f2");
    cJSON* root_body_d2w1 = cJSON_GetObjectItem(root_body_day2, "day");
    printf("日期: %s\n",root_body_d2w1->valuestring);

    cJSON* root_body_d2w2 = cJSON_GetObjectItem(root_body_day2, "day_weather");
    printf("日间天气: %s\n",root_body_d2w2->valuestring);

    cJSON* root_body_d2w3 = cJSON_GetObjectItem(root_body_day2, "night_weather");
    printf("夜间天气: %s\n",root_body_d2w3->valuestring);

    cJSON* root_body_d2w4 = cJSON_GetObjectItem(root_body_day2, "day_air_temperature");
    printf("日间温度: %s\n",root_body_d2w4->valuestring);

    cJSON* root_body_d2w5 = cJSON_GetObjectItem(root_body_day2, "night_air_temperature");
    printf("夜间温度: %s\n\n",root_body_d2w5->valuestring);

    printf("城市: %s\n",cJSON_GetObjectItem(root_body_city_info, "c5")->valuestring);

    cJSON* root_body_day3 = cJSON_GetObjectItem(root_body, "f3");
    cJSON* root_body_d3w1 = cJSON_GetObjectItem(root_body_day3, "day");
    printf("日期: %s\n",root_body_d3w1->valuestring);

    cJSON* root_body_d3w2 = cJSON_GetObjectItem(root_body_day3, "day_weather");
    printf("日间天气: %s\n",root_body_d3w2->valuestring);

    cJSON* root_body_d3w3 = cJSON_GetObjectItem(root_body_day3, "night_weather");
    printf("夜间天气: %s\n",root_body_d3w3->valuestring);

    cJSON* root_body_d3w4 = cJSON_GetObjectItem(root_body_day3, "day_air_temperature");
    printf("日间温度: %s\n",root_body_d3w4->valuestring);

    cJSON* root_body_d3w5 = cJSON_GetObjectItem(root_body_day3, "night_air_temperature");
    printf("夜间温度: %s\n\n",root_body_d3w5->valuestring);

    cJSON_Delete(root);                                                           //将json结构占用的数据空间释放

    return 0;
}

cJSON部分:

链接:https://pan.baidu.com/s/1zLebKOF7NHqF7f8Spl7G_Q 
提取码:2u0j 

解压后将文件放在main.c同目录下:

终端编译指令:  gcc main.c cJSON.c -L cJSON.h
终端运行指令: ./a.out 

其中request的信息需要对应下图红框内容:

char *httpRequest()
{
    
    
    static char request[1024];
    printf("请求获取信息!\n\n");
    snprintf(request, 1024, "GET /spot-to-weather?area=广州 HTTP/1.1\r\n"
                            "Host:weather01.market.alicloudapi.com\r\n"
                            "Authorization:APPCODE 8b75a70400042069f49902b27af45\r\n"
                            "\r\n");
    return request;
}

在这里插入图片描述

在这里插入图片描述

cJSON的用法:https://www.cnblogs.com/catgatp/p/6379955.html

猜你喜欢

转载自blog.csdn.net/weixin_43793181/article/details/108520621
今日推荐