使用c语言编写一个简单的JSON解析器,能够解析JSON格式的字符串,支持对象、数组、字符串、数字等数据类型。
时间: 2024-03-15 16:45:38 浏览: 85
好的,下面是一个使用C语言编写的简单的JSON解析器,可以解析符合JSON语法规则的字符串,并将其解析成对应的数据结构。
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// JSON数据类型枚举
enum json_type {
JSON_OBJECT,
JSON_ARRAY,
JSON_STRING,
JSON_NUMBER,
JSON_BOOLEAN,
JSON_NULL
};
// JSON节点结构体
struct json_node {
enum json_type type; // 节点类型
union {
char *string; // 字符串类型
double number; // 数字类型
int boolean; // 布尔类型
struct json_node *elements; // 数组类型
struct {
char *key;
struct json_node *value;
} *members; // 对象类型
} data;
int size; // 数组或对象的大小
};
// 创建一个字符串节点
struct json_node *create_string_node(char *value) {
struct json_node *node = (struct json_node *)malloc(sizeof(struct json_node));
node->type = JSON_STRING;
node->data.string = (char *)malloc(strlen(value) + 1);
strcpy(node->data.string, value);
return node;
}
// 创建一个数字节点
struct json_node *create_number_node(double value) {
struct json_node *node = (struct json_node *)malloc(sizeof(struct json_node));
node->type = JSON_NUMBER;
node->data.number = value;
return node;
}
// 创建一个布尔节点
struct json_node *create_boolean_node(int value) {
struct json_node *node = (struct json_node *)malloc(sizeof(struct json_node));
node->type = JSON_BOOLEAN;
node->data.boolean = value;
return node;
}
// 创建一个空节点
struct json_node *create_null_node() {
struct json_node *node = (struct json_node *)malloc(sizeof(struct json_node));
node->type = JSON_NULL;
return node;
}
// 解析一个字符串
char *parse_string(char *json_string, int *pos) {
char *value = NULL;
int start = ++(*pos);
while (json_string[*pos] != '"') {
(*pos)++;
}
int end = *pos;
int len = end - start;
if (len > 0) {
value = (char *)malloc(len + 1);
strncpy(value, json_string + start, len);
value[len] = '\0';
}
(*pos)++;
return value;
}
// 解析一个数字
double parse_number(char *json_string, int *pos) {
double value = 0.0;
int start = *pos;
while (json_string[*pos] == '-' || (json_string[*pos] >= '0' && json_string[*pos] <= '9') || json_string[*pos] == '.' || json_string[*pos] == 'e' || json_string[*pos] == 'E') {
(*pos)++;
}
int end = *pos;
int len = end - start;
if (len > 0) {
char *number_str = (char *)malloc(len + 1);
strncpy(number_str, json_string + start, len);
number_str[len] = '\0';
value = atof(number_str);
free(number_str);
}
return value;
}
// 解析一个数组
struct json_node *parse_array(char *json_string, int *pos) {
struct json_node *node = (struct json_node *)malloc(sizeof(struct json_node));
node->type = JSON_ARRAY;
node->size = 0;
node->data.elements = NULL;
(*pos)++;
while (json_string[*pos] != ']') {
if (node->size > 0) {
(*pos)++;
}
struct json_node *element = parse_value(json_string, pos);
node->size++;
node->data.elements = (struct json_node *)realloc(node->data.elements, node->size * sizeof(struct json_node));
node->data.elements[node->size - 1] = *element;
free(element);
}
(*pos)++;
return node;
}
// 解析一个对象
struct json_node *parse_object(char *json_string, int *pos) {
struct json_node *node = (struct json_node *)malloc(sizeof(struct json_node));
node->type = JSON_OBJECT;
node->size = 0;
node->data.members = NULL;
(*pos)++;
while (json_string[*pos] != '}') {
if (node->size > 0) {
(*pos)++;
}
char *key = parse_string(json_string, pos);
(*pos)++;
struct json_node *value = parse_value(json_string, pos);
node->size++;
node->data.members = (struct json_node *)realloc(node->data.members, node->size * sizeof(struct json_node));
node->data.members[node->size - 1].key = key;
node->data.members[node->size - 1].value = value;
}
(*pos)++;
return node;
}
// 解析一个值
struct json_node *parse_value(char *json_string, int *pos) {
while (json_string[*pos] == ' ' || json_string[*pos] == '\n' || json_string[*pos] == '\r' || json_string[*pos] == '\t') {
(*pos)++;
}
if (json_string[*pos] == '"') {
return create_string_node(parse_string(json_string, pos));
} else if (json_string[*pos] == '-' || (json_string[*pos] >= '0' && json_string[*pos] <= '9')) {
return create_number_node(parse_number(json_string, pos));
} else if (json_string[*pos] == 't' || json_string[*pos] == 'f') {
return create_boolean_node(json_string[*pos] == 't' ? 1 : 0);
} else if (json_string[*pos] == 'n') {
(*pos) += 4;
return create_null_node();
} else if (json_string[*pos] == '[') {
return parse_array(json_string, pos);
} else if (json_string[*pos] == '{') {
return parse_object(json_string, pos);
}
return NULL;
}
// 解析一个JSON字符串
struct json_node *parse_json_string(char *json_string) {
int pos = 0;
return parse_value(json_string, &pos);
}
// 打印一个JSON节点
void print_json_node(struct json_node *node) {
switch (node->type) {
case JSON_OBJECT:
printf("{\n");
for (int i = 0; i < node->size; i++) {
printf(" \"%s\": ", node->data.members[i].key);
print_json_node(node->data.members[i].value);
if (i < node->size - 1) {
printf(",\n");
}
}
printf("\n}");
break;
case JSON_ARRAY:
printf("[\n");
for (int i = 0; i < node->size; i++) {
printf(" ");
print_json_node(&node->data.elements[i]);
if (i < node->size - 1) {
printf(",\n");
}
}
printf("\n]");
break;
case JSON_STRING:
printf("\"%s\"", node->data.string);
break;
case JSON_NUMBER:
printf("%f", node->data.number);
break;
case JSON_BOOLEAN:
printf("%s", node->data.boolean ? "true" : "false");
break;
case JSON_NULL:
printf("null");
break;
}
}
// 释放一个JSON节点
void free_json_node(struct json_node *node) {
if (node == NULL) {
return;
}
switch (node->type) {
case JSON_OBJECT:
for (int i = 0; i < node->size; i++) {
free(node->data.members[i].key);
free_json_node(node->data.members[i].value);
}
free(node->data.members);
break;
case JSON_ARRAY:
for (int i = 0; i < node->size; i++) {
free_json_node(&node->data.elements[i]);
}
free(node->data.elements);
break;
case JSON_STRING:
free(node->data.string);
break;
}
free(node);
}
int main() {
char *json_string = "{\"name\": \"Alice\", \"age\": 30, \"is_student\": true, \"grades\": [90, 85, 95]}";
struct json_node *root = parse_json_string(json_string);
print_json_node(root);
printf("\n");
free_json_node(root);
return 0;
}
```
这个JSON解析器使用递归下降解析的方法,根据JSON的语法规则逐个解析JSON字符串中的字符,生成对应的节点,并将它们组合成一个完整的JSON对象。
希望这个代码可以帮助您开始编写自己的JSON解析器。
阅读全文