本文最后更新于 109 天前,其中的信息可能已经有所发展或是发生改变。
/**
* @filename: jsonparsing.c
* @brief: 建立tcp连接,向api接口请求天气数据。并对返回的JSON字符串解析
* @author: philia
* @date: 2026/4/25
* @version: ver1.0
* @note none
* CopyRight (c) 2026 philia All Right Reseverd
*/
#include <stdio.h>
#include <arpa/inet.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "cJSON.h"
//HTTP端口
#define PORT 80
//请求api服务器IP
#define IP "116.62.81.138"
// JSON解析函数
void parse_weather(const char *json_str)
{
cJSON *root = cJSON_Parse(json_str);
if (root == NULL) {
printf("JSON parse error\n");
return;
}
// 第一层:results 数组
cJSON *results = cJSON_GetObjectItem(root, "results");
if (!cJSON_IsArray(results)) {
printf("results is not an array\n");
cJSON_Delete(root);
return;
}
// 遍历数组
int arr_size = cJSON_GetArraySize(results);
for (int i = 0; i < arr_size; i++) {
cJSON *item = cJSON_GetArrayItem(results, i);
if (item == NULL) continue;
// 获取 location 对象
cJSON *location = cJSON_GetObjectItem(item, "location");
if (cJSON_IsObject(location)) {
// 提取 location 下的各个字段
cJSON *loc_name = cJSON_GetObjectItem(location, "name");
cJSON *loc_path = cJSON_GetObjectItem(location, "path");
printf("=== Location ===\n");
if (cJSON_IsString(loc_name)) printf("name: %s\n", loc_name->valuestring);
if (cJSON_IsString(loc_path)) printf("path: %s\n", loc_path->valuestring);
}
// 获取 last_update
cJSON *last_update = cJSON_GetObjectItem(item, "last_update");
if (cJSON_IsString(last_update))
printf("last_update: %s\n", last_update->valuestring);
}
// 释放 root
cJSON_Delete(root);
}
int main(int argc, const char *argv[])
{
int tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
if (tcp_socket == -1)
{
fprintf(stderr, "tcp_socket error, errno:%d,%s", errno, strerror(errno));
exit(-1);
}
struct sockaddr_in dest_addr;
memset(&dest_addr, 0, sizeof(dest_addr)); // 清空结构体
dest_addr.sin_family = AF_INET; // IPv4
dest_addr.sin_port = htons(PORT); // 端口号(转为网络字节序)
inet_pton(AF_INET, IP, &dest_addr.sin_addr); // 目标 IP
socklen_t size = sizeof(dest_addr);
int isconnect = connect(tcp_socket, (struct sockaddr *)&dest_addr, size);
if (isconnect != 0)
{
fprintf(stderr, "connect error, errno:%d,%s", errno, strerror(errno));
exit(-1);
}
char input[4096] = {0};
char result[4096] = {0};
sprintf(input, "GET https://api.seniverse.com/v3/weather/now.json?key=S_-0v50j_wqkFuC9Q&location=Guiyang&language=en&unit=c "
"HTTP/1.1"
"\r\n"
"Host:api.seniverse.com\r\n"
"\r\n");
memset(result, 0, sizeof(result));
send(tcp_socket, input, strlen(input), 0);
while (1)
{
// 接收服务端传回的结果并打印
recv(tcp_socket, result, sizeof(result), 0);
memset(result, 0, sizeof(result));
recv(tcp_socket, result, sizeof(result), 0);
//printf("Result:\n%s\n", result);
break;
}
//解析JOSN
cJSON *json = cJSON_Parse(result);
//char *string = cJSON_Print(json);
parse_weather(cJSON_Print(json));
//printf("%s\n", string);
return 0;
}


