当我们需要获取某个Web API的数据时,一般情况下会返回JSON格式的数据。如何使用C语言来解析这些JSON数据呢?这时候,就可以使用cJSON开源库。
cJSON是一款轻量级、快速的C语言JSON解析器。它使用简单,只需要包含一个头文件"cJSON.h",并将相关代码文件加入到项目中即可。下面将详细讲解cJSON解析JSON格式的全过程。
第一步:安装cJSON
可以通过github下载cJSON代码,然后将cJSON.c和cJSON.h文件加入到项目中即可。
第二步:获取JSON数据
我们需要先获取Web API的数据,这里我们可以使用CURL库来发送网络请求,获取JSON数据,例如:
#include <stdio.h>
#include <stdlib.h>
#include <curl/curl.h>
int main(int argc, char *argv[]) {
CURL *curl;
CURLcode res;
curl = curl_easy_init(); // 初始化CURL
if (curl) {
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/api/users");
res = curl_easy_perform(curl); // 执行请求
if (res != CURLE_OK) { // 如果请求失败
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
}
curl_easy_cleanup(curl); // 清理CURL
}
return 0;
}
执行上面的代码,可以得到JSON格式的数据。如下所示:
{
"status": "success",
"users": [
{
"id": 1,
"name": "John Doe",
"email": "john.doe@example.com"
},
{
"id": 2,
"name": "Jane Doe",
"email": "jane.doe@example.com"
}
]
}
第三步:解析JSON数据
我们已经获得了JSON格式的数据,接下来我们需要将它解析成我们所需要的数据。
首先,我们创建一个cJSON对象(通过调用cJSON_Parse函数),并将JSON格式的数据作为参数传入:
cJSON *root = cJSON_Parse(json_data);
其中,json_data是我们获取到的JSON数据。
然后,就可以通过cJSON提供的接口获取JSON对象的值了。例如,要获取上述JSON中每个用户的名称,可以像这样:
cJSON *users = cJSON_GetObjectItem(root, "users");
if (users) {
cJSON *user = NULL;
cJSON_ArrayForEach(user, users) { // 遍历users数组
cJSON *name = cJSON_GetObjectItem(user, "name");
printf("username: %s\n", name->valuestring);
}
}
另外,cJSON还提供了一些方便的宏,比如cJSON_GetArrayItem、cJSON_GetObjectItemCaseSensitive等,用于获取数组项、大小写敏感对象值等。
示例一
下面是一个完整的程序,展示如何使用cJSON解析JSON数据,并打印每个用户的名称:
#include <stdio.h>
#include <stdlib.h>
#include <curl/curl.h>
#include "cJSON.h"
int main(int argc, char *argv[]) {
CURL *curl;
CURLcode res;
curl = curl_easy_init(); // 初始化CURL
if (curl) {
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/api/users");
res = curl_easy_perform(curl); // 执行请求
if (res == CURLE_OK) { // 如果请求成功
char *json_data = NULL;
cJSON *root = NULL;
curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &json_data);
if (json_data && strstr(json_data, "application/json")) { // 只解析JSON格式的数据
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &res);
if (res == 200) { // 只解析请求成功的响应
curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &len); // 获取下载的数据长度
json_data = (char *) malloc((len+1) * sizeof(char)); // 分配内存
if (json_data) {
curl_easy_getinfo(curl, CURLINFO_DATA_OUT, &json_data); // 以字符串形式获取数据
json_data[len] = '\0';
root = cJSON_Parse(json_data); // 将json_data解析成cJSON对象
if (root) {
cJSON *users = cJSON_GetObjectItem(root, "users");
if (users) {
cJSON *user = NULL;
cJSON_ArrayForEach(user, users) { // 遍历users数组
cJSON *name = cJSON_GetObjectItem(user, "name");
if (name) {
printf("username: %s\n", name->valuestring);
}
}
}
cJSON_Delete(root); // 删除cJSON对象
}
free(json_data); // 释放内存
}
}
}
}
curl_easy_cleanup(curl); // 清理CURL
}
return 0;
}
示例二
下面是一个更复杂的示例,展示如何从复杂的JSON数据中解析出我们需要的值:
{
"status": "success",
"result": {
"total": 2,
"data": [
{
"id": 1,
"name": {
"first": "John",
"last": "Doe"
},
"email": "john.doe@example.com",
"addresses": [
{
"street": "123 Main Street",
"city": "Anytown",
"state": "CA",
"zip": "12345"
},
{
"street": "456 Maple Street",
"city": "Othertown",
"state": "NY",
"zip": "67890"
}
]
},
{
"id": 2,
"name": {
"first": "Jane",
"last": "Doe"
},
"email": "jane.doe@example.com",
"addresses": [
{
"street": "789 Elm Street",
"city": "Sometown",
"state": "FL",
"zip": "13579"
}
]
}
]
}
}
要获取每个用户的名称和地址,可以像这样:
cJSON *result = cJSON_GetObjectItem(root, "result");
if (result) {
cJSON *data = cJSON_GetObjectItem(result, "data");
if (data) {
cJSON *user = NULL;
cJSON_ArrayForEach(user, data) { // 遍历data数组
cJSON *name = cJSON_GetObjectItem(user, "name");
if (name) {
cJSON *first = cJSON_GetObjectItem(name, "first");
cJSON *last = cJSON_GetObjectItem(name, "last");
printf("username: %s %s\n", first->valuestring, last->valuestring);
}
cJSON *addresses = cJSON_GetObjectItem(user, "addresses");
if (addresses) {
cJSON *address = NULL;
cJSON_ArrayForEach(address, addresses) { // 遍历addresses数组
cJSON *street = cJSON_GetObjectItem(address, "street");
cJSON *city = cJSON_GetObjectItem(address, "city");
cJSON *state = cJSON_GetObjectItem(address, "state");
cJSON *zip = cJSON_GetObjectItem(address, "zip");
printf("%s, %s, %s %s\n", street->valuestring, city->valuestring, state->valuestring, zip->valuestring);
}
}
}
}
}
最后一步:清理
最后,我们需要在程序结束时清理cJSON对象和其他资源:
cJSON_Delete(root);
这样,我们就可以顺利地完成JSON数据的解析了。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言利用cJSON解析JSON格式全过程 - Python技术站