基於伺服器響應的實時天氣資料進行JSON解析的詳細程式碼及其框架

小楠同志發表於2024-06-11
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/udp.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include "cJSON.h"

#define PORT 80  //埠號
#define IPADDR "116.62.81.138"//地址

#define KEY "SNGgI2upxur590NHn" // 私鑰
#define LOCAL "beijing" //城市

int main(int argc, char const *argv[])
{
    // 1.建立TCP套接字
    int tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
    //錯誤處理
    if (tcp_socket == -1)
    {
        fprintf(stderr, "tcp socket error,errno:%d,%s\n", errno, strerror(errno));
        exit(1);
    }
    // 2.發起連線請求,等待接受伺服器接受連線
    struct sockaddr_in dest_addr;
    dest_addr.sin_family = AF_INET;                // 協議族,是固定的
    dest_addr.sin_port = htons(PORT);              // 伺服器埠,必須轉換為網路位元組序
    dest_addr.sin_addr.s_addr = inet_addr(IPADDR); // 伺服器地址
    //ret用來進行下一步的connect連線是否成功進行判斷
    int ret = connect(tcp_socket, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
    //ret = 0連線成功,ret = -1連線失敗
    if (ret < 0)
    {
        fprintf(stderr, "connect error,errno:%d,%s\n", errno, strerror(errno));
        exit(1);
    }
    // 3.用於儲存HTTP的請求內容: 請求行(HRI+(空格))+ 請求欄位 + \r\n + 請求包體(可選)+\r\n
    char reqbuf[1024] = {0};
    sprintf(reqbuf, "GET https://api.seniverse.com/v3/weather/now.json?key=%s&location=%s&language=en&unit=c "
                    "HTTP/1.1"
                    "\r\n"
                    "Host:api.seniverse.com\r\n"
                    "\r\n",
            KEY, LOCAL);

    // 4.說明雙方建立連線,此時可以利用HTTP協議傳送請求資訊,並等待伺服器的響應  基於請求/響應
    send(tcp_socket, reqbuf, strlen(reqbuf), 0);

    // 5.等待伺服器的響應
    char recvbuf[1024] = {0};

    recv(tcp_socket, recvbuf, sizeof(recvbuf), 0); // 第一次返回的響應引數
    printf("%s", recvbuf);
    bzero(recvbuf, 1024);

    recv(tcp_socket, recvbuf, sizeof(recvbuf), 0); // 第二次返回的響應包體
    printf("%s\n", recvbuf);

    // 6.對響應包體進行JSON解析

    // 1) 先把獲取的字串轉換為JSON格式
    cJSON *obj = cJSON_Parse(recvbuf);

    // 2) 把解析之後的JSON格式進行輸出,用於除錯
    printf("%s\n", cJSON_Print(obj));

    // 3) 對JSON格式進行解析
    cJSON *results = NULL;
    results = cJSON_GetObjectItem(obj, "results");
    printf("array size = %d\n", cJSON_GetArraySize(results));

    // 4)對城市的實時溫度資料進行解析
    cJSON *result = NULL;
    cJSON_ArrayForEach(result, results)
    {
    cJSON *now = cJSON_GetObjectItem(result, "now");
    cJSON *temperature = cJSON_GetObjectItem(now, "temperature");

    printf("temperature : %s\n", temperature->valuestring);

    printf("temperature : %d\n", atoi(temperature->valuestring));
    }

    return 0;
}

相關文章