• c语言-手写JSON解析


    c语言-手写JSON解析

    什么是JSON?

    SON(JavaScript Object Notation)是一种轻量级的数据交换格式,用来传输属性值或者序列性的值组成的数据对象。

    JSON是JavaScript的一个子集。

    具有良好的可读性和便于快速编写的特性。

    JSON是独立于语言的文本格式,并且采用了类似C语言家族的一些习惯。

    JSON数据格式与语言无关,是目前网络中主流的数据传输格式之一,使用率几乎为99%。

    JSON支持的数据类型

    JSON里面的数据以一种键值对的方式存在,即“key”:“value” 类型可以是数据类型中的任意一种:

    JSON语法规则

    JSON的语法规则非常简单,使用

    大括号——{}
    中括号——[]
    逗号——,
    冒号——:
    双引号——“” (一般可以不需要)

    JSON的解析

    在解析JSON是我们会遇到两种情况,其一是解析大括号——{}类型,其二是解析中括号类型——[],以及这两种类型的组合模式。

    JSON基本语法

    对象类型(Object)

    {
        "name" : "佩奇" ,
        "age" : "8"
    }
    
    • 1
    • 2
    • 3
    • 4

    数组类型(Array)

    [
    "喜羊羊","懒羊羊",5,true,null
    ]
    
    • 1
    • 2
    • 3

    对象组合形

    {
        "name" : "佩奇" ,  
        "age" : "8",
        "friend" :[{"name" : " 喜羊羊 " , "age" : "5"} , {"name" : " 懒羊羊 " , "age" : "6"}]
        //对象类型嵌套数组类型,数组类型嵌套对象类型
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    数组组合型

    
    [ [{"name" : "佩奇" ,"age" : "8"},{"name" : "佩奇" ,"age" : "8"}],[{},{}]]
    
    • 1
    • 2

    编写解析器

    头文件

    //
    // Created by huanmin on 2022/9/15.
    //
    
    #ifndef STUDY_JSON_H
    #define STUDY_JSON_H
    #include "../util/str_util.h"
    #include 
    #include "charhashmap.h"
    #include "charlist.h"
    #include "../util/assertmy.h"
    static char *str_to_json_placeholder(char *string, CharHashMap *map, CharHashMap *list);
    static char *querySubstitute(char *string, CharHashMap *map, CharHashMap *list);
    BOOL str_is_json(char *string);
    CharList *str_to_json_array(char *array);
    CharHashMap *str_to_json_map(char *dict);
    char *map_to_json_str(CharHashMap *pMap);
    char *array_to_json_str(CharList *pCharlist);
    BOOL str_is_map(char *str);
    BOOL str_is_array(char *str);
    #endif //STUDY_JSON_H
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    实现文件

    //
    // Created by huanmin on 2022/9/15.
    //
    
    #include "json.h"
    
    
    //转换字符串为JSON_先进行占位符替换
    static char *str_to_json_placeholder(char *string, CharHashMap *map, CharHashMap *list) {
        //判断是否有[],如果有那么提取出来,并且将位置上的内容替换为 @arri
        int zi = 0;
        int start = -1;
        while ((start = str_find(string, "[")) != -1) {
            int length = str_length(string);
            int jilu = 0;
            int end = -1;
            for (int i = start; i < length; ++i) {
                if (string[i] == '[') {
                    jilu++;
                }
                if (string[i] == ']') {
                    jilu--;
                    if (jilu == 0) {
                        end = i;
                        break;
                    }
                }
            }
            char *arr_str = str_substring(string, start, end);
            char *append = str_concat(3, "@arr", int_to_str(zi), "@");
            putCharHashMap(list, append, arr_str);
            string = str_replace(string, arr_str, append);
            zi++;
        }
        zi = 0;
        start = -1;
        //判断是否有{},如果有那么提取出来, 并且将位置上的内容替换为@mapi
        while ((start = str_find(string, "{")) != -1) {
            int length = str_length(string);
            int jilu = 0;
            int end = -1;
            for (int i = start; i < length; ++i) {
                if (string[i] == '{') {
                    jilu++;
                }
                if (string[i] == '}') {
                    jilu--;
                    if (jilu == 0) {
                        end = i;
                        break;
                    }
                }
    
            }
    
            char *map_str = str_substring(string, start, end);
            char *append = str_concat(3, "@map", int_to_str(zi), "@");
            putCharHashMap(map, append, map_str);
            string = str_replace(string, map_str, append);
            zi++;
        }
        return string;
    }
    
    static char *querySubstitute(char *string, CharHashMap *map, CharHashMap *list) {
        char *str = string;
        int start = -1;
        //替换
        if (str_start_with(string, "@map")) {
            while ((start = str_find(str, "@map")) != -1) {
                int end = str_find_n(str, "@", start + 1, str_length(str));
                char *substring = str_substring(str, start, end);
                str = (char *) getCharHashMap(map, substring);
            }
        } else if (str_start_with(string, "@arr")) {
            //替换参数为原来的值
            while ((start = str_find(str, "@arr")) != -1) {
                int end = str_find_n(str, "@", start + 1, str_length(str));
                char *substring = str_substring(str, start, end);
                str = (char *) getCharHashMap(list, substring);
            }
        }
        start = -1;
        //判断是否还包含@map或者@arr,如果有那么就继续替换
        while ((start = str_find(str, "@map")) != -1 || (start = str_find(str, "@arr")) != -1) {
            //截取所有的@map@和@arr@,并且将其替换为原来的字符串
            CharList *pCharlist = createCharList(10);
            while ((str_find_n(str, "@map", start, str_length(str))) != -1 ||
                   (str_find_n(str, "@arr", start, str_length(str))) != -1) {
                int end = str_find_n(str, "@", start + 1, str_length(str));
                char *substring = str_substring(str, start, end);
                addCharList(pCharlist, substring);
                start = end;
            }
            CharListIterator *pIterator = createCharListIterator(pCharlist);
            while (hasNextCharListIterator(pIterator)) {
                char *key = nextCharListIterator(pIterator);
                if (str_start_with(key, "@map")) {
                    char *value = (char *) getCharHashMap(map, key);
                    str = str_replace(str, key, value);
                } else if (str_start_with(key, "@arr")) {
                    char *value = (char *) getCharHashMap(list, key);
                    str = str_replace(str, key, value);
                }
            }
        }
        return str;
    }
    
    
    //将字符串数组格式[1,2,3]或者[{a:b,c:d},{a:b,c:d}]转换为List  ,(没有任何格式验证,全靠自己规范编写)
    CharList *str_to_json_array(char *array) {
        if (array == NULL || str_length(array) == 0) {
            return NULL;
        }
        char *trim = str_trim(array);
        char *string = str_substring(trim, 1, str_length(trim) - 2);
        CharHashMap *map = createCharHashMap(10);
        CharHashMap *list = createCharHashMap(10);
        char *string1 = str_to_json_placeholder(string, map, list);
        CharList *pCharlist = str_split(string1, ",");
        for (int i = 0; i < pCharlist->len; ++i) {
            char *v = pCharlist->str[i];
            pCharlist->str[i] = querySubstitute(v, map, list);
        }
        return pCharlist;
    }
    
    
    //将json对象字符串{a:b,c:d},转换为hashMap  ,(没有任何格式验证,全靠自己规范编写)
    CharHashMap *str_to_json_map(char *dict) {
        if (dict == NULL || str_length(dict) == 0) {
            return NULL;
        }
        char *trim = str_trim(dict);
        char *string = str_substring(trim, 1, str_length(trim) - 2);
        CharHashMap *map = createCharHashMap(10);
        CharHashMap *list = createCharHashMap(10);
        char *string1 = str_to_json_placeholder(string, map, list);
        CharList *pCharlist = str_split(string1, ",");
        int str_len = pCharlist->len;
        if (str_len == 0) {
            return NULL;
        }
        //分割key和value
        CharHashMap *pMap = createCharHashMap(str_len);
        for (int i = 0; i < str_len; i++) {
            char *str = pCharlist->str[i];
            CharList *pList = str_split(str, ":");
            char *key = str_trim(pList->str[0]);
            char *value = str_trim(pList->str[1]);
            putCharHashMap(pMap, key, querySubstitute(value, map, list));
        }
        return pMap;
    }
    
    
    
    //将hashMap转换为json对象{a:b,c:d,v:[1,2],f:{a:b,c:d}} ,(没有任何格式验证,全靠自己规范编写)
    char *map_to_json_str(CharHashMap *pMap) {
        if (pMap == NULL) {
            return NULL;
        }
        char *string = str_create("{");
        int len = pMap->size;
        //创建迭代器
        CharHashMapIterator *pIterator = createCharHashMapIterator(pMap);
        while (hasNextCharHashMapIterator(pIterator)) {
            CharKvLinkedNode *pNode = nextCharHashMapIterator(pIterator);
            string = str_append(string, pNode->key);
            string = str_append(string, ":");
            string = str_append(string, pNode->value);
            if (len != 1) {
                string = str_append(string, ",");
            }
            len--;
        }
        string = str_append(string, "}");
        return string;
    }
    
    //将CharList转换为json数组格式[1,2,[1,2,3]]或者[{},{}] ,(没有任何格式验证,全靠自己规范编写)
    char *array_to_json_str(CharList *pCharlist) {
        if (pCharlist == NULL) {
            return NULL;
        }
        char *string = str_create("[");
        for (int i = 0; i < pCharlist->len; ++i) {
            string = str_append(string, pCharlist->str[i]);
            if (i != pCharlist->len - 1) {
                string = str_append(string, ",");
            }
        }
        string = str_append(string, "]");
        return string;
    }
    
    //判断是否是json对象
    BOOL str_is_map(char *str) {
        if (str == NULL) {
            return FALSE;
        }
        if (str_length(str) < 2) {
            return FALSE;
        }
        if (str_start_with(str, "{") && str_end_with(str, "}")) {
            return TRUE;
        }
        return FALSE;
    }
    
    //判断是否是数组
    BOOL str_is_array(char *str) {
        if (str == NULL) {
            return FALSE;
        }
        if (str_length(str) < 2) {
            return FALSE;
        }
        if (str_start_with(str, "[") && str_end_with(str, "]")) {
            return TRUE;
        }
        return FALSE;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224

    在这里插入图片描述

    点赞 -收藏-关注-便于以后复习和收到最新内容
    有其他问题在评论区讨论-或者私信我-收到会在第一时间回复
    在本博客学习的技术不得以任何方式直接或者间接的从事违反中华人民共和国法律,内容仅供学习、交流与参考
    免责声明:本文部分素材来源于网络,版权归原创者所有,如存在文章/图片/音视频等使用不当的情况,请随时私信联系我、以迅速采取适当措施,避免给双方造成不必要的经济损失。
    感谢,配合,希望我的努力对你有帮助^_^
  • 相关阅读:
    servlet的简单使用总结
    Qt全球峰会2023中国站 参会概要
    如何用PHP语言实现远程语音播报
    c++图像腐蚀操作
    Redis缓存问题
    图像分割之k-means聚类分割
    一本通1059;求平均年龄
    为何重要?解析企业实行网络安全等级保护的必要性
    【鸿蒙OS】【ArkUI】鸿蒙OS UI布局适配终极攻略
    释放DOE的能量,快速确定最佳工艺设置,节省时间、成本和资源
  • 原文地址:https://blog.csdn.net/weixin_45203607/article/details/126888232