目录
-
题目
- 注意事项
- 实现代码
- 结果展示
- 相关接口指引
题目
利用某些平台(聚合API、百度AI、科大讯飞API)的API接口,利用HTTP协议向服务器发送请求,并接受服务器的响应,要求利用cJSON库对服务器的响应数据进行解析,并输出到终端。
注意事项
1.预测的日期开始时间为2010-01-01
2.”老黄历”API 服务器返回值是将响应包体与响应行一同返回,所以该程序只需要对服务器返回值接收一次,再利用strstr进行找寻响应包体,最后完成JASON格式数据的解析,但是,这种返回方式不是固定的。例如:“天气预报”API返回数据将响应行与响应包体分为两次发出,所以需要接收两次。
3.该程序代码使用了cJSON库,所以需要用户提前下载并将cJSON.c和cJSON.h加入程序文档。
实现代码
/********************************************************************************
*
* file name: demo.c
* author : ProgramMonkey_Fly@126.com
* date : 2024/06/11
* function :
* 该案例是学习掌握对JSON格式服务器响应数据的解析与构造
* 使用“聚合数据”官网提供的免费接口“老黄历”作为学习例子
* note :
* 1.预测的日期开始时间为2010-01-01
* 2."老黄历"API 服务器返回值是将响应包体与响应行一同返回,所以该程序只需要
* 对服务器返回值接收一次,再利用strstr进行找寻响应包体,最后完成JASON
* 格式数据的解析,但是,这种返回方式不是固定的。例如:“天气预报”API返回
* 数据将响应行与响应包体分为两次发出,所以需要接收两次。
* 3.该程序代码使用了cJSON库,所以需要用户提前下载并将cJSON.c和cJSON.h加入
* 程序文档。
* version :
*
* CopyRight (c) 2023-2024 ProgramMonkey_Fly@126.com All Right Reseverd
*
* ******************************************************************************/
/****************************头文件*********************************************/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "cJSON.h"
#include
/****************************宏定义*********************************************/
#define HOST "v.juhe.cn" //服务器域名
#define PORT 80 //http协议端口号
#define BUFSIZE 4096 //自定义缓冲区大小
#define KEY "..." //API需要的密钥(在个人中心->我的数据,接口名称上方查看)
#define DATE "2024-06-12" //想要预测日期,格式2014-09-09
int main(int argc, char **argv)
{
//创建TCP的套接字文件
int tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
if(tcp_socket == -1)
{
fprintf(stderr, "tcp socket error,errno:%d,%sn",errno,strerror(errno));
exit(1);
}
//向服务器发送请求之前,需要设置目标端口和目标地址
struct sockaddr_in dest_addr;
socklen_t flag_dest = sizeof(dest_addr);
dest_addr.sin_family = AF_INET; //协议族,是固定的
dest_addr.sin_port = htons(PORT); //服务器运行进程的端口号,必须转换为网络字节序
//利用gethostbyname函数接口,获取服务器域名所包含的信息---即获取服务器的ip
struct hostent *hostent = gethostbyname(HOST);
if(hostent == NULL)
{
fprintf(stderr, "ip get error,errno:%d,%sn",errno,strerror(errno));
exit(2);
}
//存储服务器IP地址,必须转换为点分十进制字符串形式
dest_addr.sin_addr.s_addr = inet_addr("203.107.54.210");
//使用connect函数接口向服务器发起连接申请
int flag_connect = connect(tcp_socket, (struct sockaddr *)&dest_addr, flag_dest);
if(flag_connect == -1)
{
fprintf(stderr, "connect socket error,errno:%d,%sn",errno,strerror(errno));
exit(3);
}
//连接成功后,向服务器发送请求
char buf[BUFSIZE] = {0};
sprintf(buf, "POST http://v.juhe.cn/laohuangli/d?key=%s&date=%s HTTP/1.1rn"
"HOST: %srn"
"Content-Type: application/x-www-form-urlencodedrn"
"rn"
,KEY
,DATE
,HOST);
int ret = write(tcp_socket,buf,strlen(buf));
if (ret 0)
{
memset(buf, 0, BUFSIZE);
int i = read(tcp_socket, buf, BUFSIZE);
printf("%sn", buf);
if (i == 0)
{
close(tcp_socket);//关闭套接字
fprintf(stderr,"read data fail! errno:%d, errmsg:'%s'nn",errno, strerror(errno));
exit(6);
}
break;
}
}
//对读取到的数据进行处理,由于响应包体跟响应行+响应字段粘合在一起,所以需要先对获取数据作初步处理
char *buf1 = strstr(buf, "{");
// 1. 将存储JSON格式的字符串转换成JASON格式数据
cJSON *json = cJSON_Parse(buf1);
//2. 对转换后的数据进行输出调试
char *string = cJSON_Print(json);
printf("%sn", string);
//3. 练习:利用cJSON_GetObjectItem获取指定键名的值
cJSON *result = cJSON_GetObjectItem(json, "result");
cJSON *jishen = cJSON_GetObjectItem(result, "jishen");
char *str_jishen = cJSON_Print(jishen);
printf("吉神宜趋: %sn", str_jishen);
//关闭套接字
close(tcp_socket);
return 0;
}
结果展示
相关接口指引
- 一般嵌入式开发中可以使用cJSON库对JSON格式进行解析,cJSON库是基于C语言的一个开源项目,github下载地址:https://github.com/DaveGamble/cJSON
- 免费API接口工具大全 – 聚合数据 (juhe.cn)