zoukankan      html  css  js  c++  java
  • 用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;
    }
  • 相关阅读:
    工作之余
    用MFC如何高效地绘图
    C++运算符优先级
    CentOS5.9下用Kate
    3G门户网(3G.cn) 招聘 软件测试工程师
    深圳市东润信息咨询有限公司招聘职位: 3G无线产品经理
    广州杰赛科技股份有限公司 招聘 技术中心3G协议软件工程师
    3G门户网(3G.cn) 招聘 手机游戏开发工程师
    3G门户网(3G.cn) 招聘 技术支持工程师
    3G工程师:三大热门的3G职业资格培训认证
  • 原文地址:https://www.cnblogs.com/grj001/p/12224044.html
Copyright © 2011-2022 走看看