JSON(JavaScript Object Notation)是一种轻量级的文本数据交换格式,易于让人阅读。同时也易于机器解析和生成。尽管JSON是Javascript的一个子集,但JSON是独立于语言的文本格式,并且采用了类似于C语言家族的一些习惯。JSON解析器和JSON库支持许多不同的编程语言。
几乎所有与网页开发相关的语言都有JSON库。JSON比XML更小、更快。
JSON用于描述数据结构,有以下形式存在:
(1)、对象(object):一个对象以”{“开始,并以”}”结束。一个对象包含一系列非排序的名称/值对,每个名称/值对之间使用”,”分隔。
(2)、名称/值(collection):名称和值之间使用”:”隔开。一个名称是一个字符串;一个值 (value)可以是双引号括起来的字符串(string)、数值(number)、true、false、null、对象(object)或者数组(array)。这些结构可以嵌套。
JSON语法规则:(1)、数据在键值对中;(2)、数据由逗号分隔;(3)、花括号保存对象;(4)、方括号保存数组。
JSON的值可以是:
(1)、数值:一系列0--9的数字组合,可以为负数或者小数。还可以用”e”或者”E”表示为指数形式。数值(number)也与C或者Java的数值非常相似。除去未曾使用的八进制与十六进制格式。除去一些编码细节。
(2)、字符串:以""括起来的一串字符。字符串(string)是由双引号包围的任意数量Unicode字符的集合,使用反斜线转义。一个字符(character)即一个单独的字符串(character string)。字符串(string)与C或者Java的字符串非常相似。
(3)、布尔值:表示为true或者false。
(4)、数组(Array):数组是值(value)的有序集合。一个数组以”[“(左中括号)开始,”]”(右中括号)结束。值之间使用”,”(逗号)分隔。数组索引从0开始。
(5)、对象(object):对象是一个无序的”名称/值”对集合。一个对象以”{“开始,并以”}”结束。每个”名称”后跟一个”:”(冒号)。”名称/值”对之间使用”,”(逗号)分隔。
(6)、null:空白可以加入到任何符号之间。
各式各样开源的JSON库非常多,这里介绍下GitHub上DaveGamble的cJSON库的使用,地址: https://github.com/DaveGamble/cJSON ,它用起来非常方便。
关于json11的使用可以参考:https://blog.csdn.net/fengbingchun/article/details/51396932
cJSON是一个仅有一个.h文件,一个.c文件组成的JSON解析器,它是由纯C(ANSI C89)实现的,跨平台性较好。cJSON中有一个cJSON结构体。cJSON是采用链表存储的。
以下是测试代码:
#include "funset.hpp"
#include
#include
#include
#include "cJSON.h"
#ifdef _MSC_VER
#include
void utf8_to_gbk(const char* utf8, char* gbk)
{
const int maxlen = 256;
wchar_t unicode_str[maxlen];
int outlen = MultiByteToWideChar(CP_UTF8, 0, utf8, strlen(utf8), unicode_str, maxlen);
outlen = WideCharToMultiByte(CP_ACP, 0, unicode_str, outlen, gbk, 256, NULL, NULL);
gbk[outlen] = '\0';
}
#else // linux
void utf8_to_gbk(const char* utf8, char* gbk)
{
strcpy(gbk, utf8);
}
#endif
int read_file(const char* filename, char** content)
{
// open in read binary mode
FILE* file = fopen(filename, "rb");
if (file == NULL) {
fprintf(stderr, "read file fail: %s\n", filename);
return -1;
}
// get the length
fseek(file, 0, SEEK_END);
long length = ftell(file);
fseek(file, 0, SEEK_SET);
// allocate content buffer
*content = (char*)malloc((size_t)length + sizeof(""));
// read the file into memory
size_t read_chars = fread(*content, sizeof(char), (size_t)length, file);
if ((long)read_chars != length) {
fprintf(stderr, "length dismatch: %d, %d\n", read_chars, length);
free(*content);
return -1;
}
(*content)[read_chars] = '\0';
fclose(file);
return 0;
}
int test_cjson_1()
{
#ifdef __linux__
const char* filename = "testdata/cjson_test7";
#else
const char* filename = "E:/GitCode/Messy_Test/testdata/cjson_test7";
#endif
char *json = NULL;
if (read_file(filename, &json) != 0) return -1;;
if ((json == NULL) || (json[0] == '\0') || (json[1] == '\0')) {
fprintf(stderr, "file content is null\n");
return -1;
}
cJSON* item = cJSON_Parse(json + 2);
if (item == NULL) {
fprintf(stderr, "pasre json file fail\n");
return -1;
}
int do_format = 0;
if (json[1] == 'f') do_format = 1;
char *printed_json = NULL;
if (json[0] == 'b') {
// buffered printing
printed_json = cJSON_PrintBuffered(item, 1, do_format);
} else {
// unbuffered printing
if (do_format) printed_json = cJSON_Print(item);
else printed_json = cJSON_PrintUnformatted(item);
}
if (printed_json == NULL) {
fprintf(stderr, "print json fail\n");
return -1;
}
printf("%s\n", printed_json);
int num = cJSON_GetArraySize(item);
for (int i = 0; i < num; ++i) {
cJSON* arr = cJSON_GetArrayItem(item, i);
if (arr == NULL) {
fprintf(stderr, "get array item fail\n");
return -1;
}
fprintf(stdout, "has item \"City\": %d; has item \"abc\": %d\n",
cJSON_HasObjectItem(arr, "City"), cJSON_HasObjectItem(arr, "abc"));
cJSON* tmp = cJSON_GetObjectItem(arr, "City");
if (tmp != NULL)
fprintf(stdout, "key: %s, value: %s\n", tmp->string, tmp->valuestring);
}
if (item != NULL) cJSON_Delete(item);
if (json != NULL) free(json);
if (printed_json != NULL) free(printed_json);
return 0;
}
int test_cjson_2()
{
#ifdef __linux__
const char* filename = "testdata/json.data";
#else
const char* filename = "E:/GitCode/Messy_Test/testdata/json.data";
#endif
char *json = NULL;
if (read_file(filename, &json) != 0) return -1;;
if ((json == NULL) || (json[0] == '\0') || (json[1] == '\0')) {
fprintf(stderr, "file content is null\n");
return -1;
}
cJSON* items = cJSON_Parse(json);
if (items == NULL) {
fprintf(stderr, "pasre json file fail\n");
return -1;
}
char* printed_json = cJSON_PrintUnformatted(items);
if (printed_json == NULL) {
fprintf(stderr, "print json fail\n");
return -1;
}
printf("%s\n\n", printed_json);
cJSON* item = cJSON_GetObjectItem(items, "name");
fprintf(stdout, "key: %s, value: %s\n", "name", item->valuestring);
char gbk[256];
item = cJSON_GetObjectItem(items, "address");
utf8_to_gbk(item->valuestring, gbk);
fprintf(stdout, "key: %s, value: %s\n", "address", gbk);
item = cJSON_GetObjectItem(items, "age");
fprintf(stdout, "key: %s, value: %d\n", "age", item->valueint);
item = cJSON_GetObjectItem(items, "value1");
int size = cJSON_GetArraySize(item);
for (int i = 0; i < size; ++i) {
cJSON* tmp = cJSON_GetArrayItem(item, i);
int len = cJSON_GetArraySize(tmp);
fprintf(stdout, "key: %s:", "value1");
for (int j = 0; j < len; ++j) {
cJSON* tmp2 = cJSON_GetArrayItem(tmp, j);
fprintf(stdout, " %f,", tmp2->valuedouble);
}
fprintf(stdout, "\n");
}
item = cJSON_GetObjectItem(items, "value2");
size = cJSON_GetArraySize(item);
fprintf(stdout, "key: %s:", "value2");
for (int i = 0; i < size; ++i) {
cJSON* tmp = cJSON_GetArrayItem(item, i);
fprintf(stdout, " %f,", tmp->valuedouble);
}
fprintf(stdout, "\n");
item = cJSON_GetObjectItem(items, "bei_jing");
cJSON* tmp = cJSON_GetObjectItem(item, "address");
utf8_to_gbk(tmp->valuestring, gbk);
fprintf(stdout, "key: %s, value: %s\n", "address", gbk);
tmp = cJSON_GetObjectItem(item, "car");
fprintf(stdout, "key: %s, value: %d\n", "car", tmp->valueint);
tmp = cJSON_GetObjectItem(item, "cat");
fprintf(stdout, "key: %s, value: %d\n", "cat", tmp->valueint);
item = cJSON_GetObjectItem(items, "shan_dong");
tmp = cJSON_GetObjectItem(item, "address");
utf8_to_gbk(tmp->valuestring, gbk);
fprintf(stdout, "key: %s, value: %s\n", "address", gbk);
tmp = cJSON_GetObjectItem(item, "value1");
size = cJSON_GetArraySize(tmp);
for (int i = 0; i < size; ++i) {
char* names[2] = { "ji_nan", "tai_an" };
cJSON* tmp2 = cJSON_GetArrayItem(tmp, i);
cJSON* tmp3 = cJSON_GetObjectItem(tmp2, names[i]);
utf8_to_gbk(tmp3->valuestring, gbk);
fprintf(stdout, "key: %s, value: %s\n",names[i], gbk);
}
if (items != NULL) cJSON_Delete(items);
if (json != NULL) free(json);
if (printed_json != NULL) free(printed_json);
return 0;
}
其中test_cjson_2()函数是解析如下json的测试代码:
{
"name": "spring",
"address": "北京",
"age": 30,
"value1": [[23, 43, -2.3, 6.7, 90],
[-9, -19, 10, 2],
[-5, -55]],
"value2": [13.3, 1.9, 2.10],
"bei_jing": {
"address": "海淀",
"car": false,
"cat": true
},
"shan_dong": {
"address": "济南",
"value1": [{"ji_nan": "趵突泉"}, {"tai_an": "泰山"}]
}
}
程序执行结果如下:
GitHub: https://github.com/fengbingchun/Messy_Test