用C读取json文件
用C读取json文件
a
jconf_t *
read_jconf(const char *file)
{
static jconf_t conf;
// 清空数据
memset(&conf, 0, sizeof(jconf_t));
// 用于存储文件内容的字符串指针
char *buf;
// 解析文件内容后的json结构化数据
json_value *obj;
// 打开文件
FILE *f = fopen(file, "rb");
if (f == NULL) {
FATAL("Invalid config path.");
}
// 确定文件大小, 并将读取指针移回文件开始
fseek(f, 0, SEEK_END);
long pos = ftell(f);
fseek(f, 0, SEEK_SET);
if (pos < 0) {
FATAL("Invalid config path.");
}
if (pos >= MAX_CONF_SIZE) {
FATAL("Too large config file.");
}
// 根据文件大小申请内存空间, 注意这边要多申请1个字节用于存放'\0'
buf = ss_malloc(pos + 1);
if (buf == NULL) {
FATAL("No enough memory.");
}
// 读取文件内容至buff
int nread = fread(buf, pos, 1, f);
if (!nread) {
FATAL("Failed to read the config file.");
}
// 关闭文件
fclose(f);
// 关闭字符串结尾
buf[pos] = '\0'; // end of string
json_settings settings = { 0UL, 0, NULL, NULL, NULL };
char error_buf[512];
// 解析内容至结构化json数据
obj = json_parse_ex(&settings, buf, pos, error_buf);
if (obj == NULL) {
FATAL(error_buf);
}
if (obj->type == json_object) {
unsigned int i, j;
// 遍历json数据
for (i = 0; i < obj->u.object.length; i++) {
// 每一步, 都先读取键名, 然后根据value类型, 读取value内容
char *name = obj->u.object.values[i].name;
json_value *value = obj->u.object.values[i].value;
if (strcmp(name, "server") == 0) {
if (value->type == json_array) {
for (j = 0; j < value->u.array.length; j++) {
if (j >= MAX_REMOTE_NUM) {
break;
}
json_value *v = value->u.array.values[j];
char *addr_str = to_string(v);
parse_addr(addr_str, conf.remote_addr + j);
ss_free(addr_str);
conf.remote_num = j + 1;
}
} else if (value->type == json_string) {
conf.remote_addr[0].host = to_string(value);
conf.remote_addr[0].port = NULL;
conf.remote_num = 1;
}
} else if (strcmp(name, "port_password") == 0) {
if (value->type == json_object) {
for (j = 0; j < value->u.object.length; j++) {
if (j >= MAX_PORT_NUM) {
break;
}
json_value *v = value->u.object.values[j].value;
if (v->type == json_string) {
conf.port_password[j].port = ss_strndup(value->u.object.values[j].name,
value->u.object.values[j].name_length);
conf.port_password[j].password = to_string(v);
conf.port_password_num = j + 1;
}
}
}
} else if (strcmp(name, "server_port") == 0) {
conf.remote_port = to_string(value);
}
// ...
}
} else {
FATAL("Invalid config file");
}
// 释放文件内容内存空间
do {
free(buf);
buf = NULL;
} while (0);
// 释放结构化json数据空间
json_value_free(obj);
return &conf;
}
void *
ss_malloc(size_t size) {
void *tmp = malloc(size);
if (tmp == NULL)
exit(EXIT_FAILURE);
return tmp;
}

浙公网安备 33010602011771号