返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C语言实现手写JSON解析的方法详解
  • 879
分享到

C语言实现手写JSON解析的方法详解

2024-04-02 19:04:59 879人浏览 独家记忆
摘要

目录什么是JSONjsON支持的数据类型JSON语法规则JSON的解析JSON基本语法编写解析器头文件实现文件什么是JSON JSON(javascript Object Notat

什么是JSON

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

JSON是JavaScript的一个子集。

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

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

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

JSON支持的数据类型

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

JSON语法规则

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

大括号——{}

中括号——[]

逗号——,

冒号——:

双引号——“” (一般可以不需要)

JSON的解析

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

JSON基本语法

对象类型(Object)

{
    "name" : "佩奇" ,
    "age" : "8"
}

数组类型(Array)

[
"喜羊羊","懒羊羊",5,true,null
]

对象组合形

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

数组组合型

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

编写解析器

头文件

//
// Created by huanmin on 2022/9/15.
//

#ifndef STUDY_JSON_H
#define STUDY_JSON_H
#include "../util/str_util.h"
#include <stdio.h>
#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

实现文件

//
// 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;
}

到此这篇关于C语言实现手写JSON解析的方法详解的文章就介绍到这了,更多相关C语言 JSON解析内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: C语言实现手写JSON解析的方法详解

本文链接: https://lsjlt.com/news/167739.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • C语言实现手写JSON解析的方法详解
    目录什么是JSONJSON支持的数据类型JSON语法规则JSON的解析JSON基本语法编写解析器头文件实现文件什么是JSON JSON(JavaScript Object Notat...
    99+
    2024-04-02
  • Go语言实现JSON解析的方法详解
    目录1、json序列化2、Json反序列化为结构体对象3、Json反序列化为map类型4、Tag的使用在日常项目中,使用Json格式进行数据封装是比较常见的操作,看一下golang怎...
    99+
    2024-04-02
  • Go语言实现JSON解析的神器详解
    目录前言JSON解析实践标准库encoding/json第三方库json-iterator收集到开源项目jinzaigo/xutil中总结前言 php转go是大趋势,越来越多公司的p...
    99+
    2023-01-29
    Go语言解析JSON Go 解析JSON Go语言 JSON
  • Go语言JSON解析器gjson使用方法详解
    目录gjson安装使用gjson GJSON 是一个Go包,它提供了一种从json文档中获取值的快速简单的方法。它具有单行检索、点符号路径、迭代和解析 json 行等功能。 还可以查...
    99+
    2022-12-08
    Go 解析器gjson Go JSON解析器
  • Go语言代码转C语言的实现方法详解
    随着计算机科技的快速发展,编程语言也在不断涌现。其中,Go语言因其简洁、高效和并发性能而备受关注。然而,在某些特定的场景下,我们可能需要将Go语言代码转换为C语言,以提高性能或兼容性。...
    99+
    2024-03-07
    代码实现 转换方法 go到c go语言
  • Go语言怎么实现JSON解析
    这篇文章主要介绍“Go语言怎么实现JSON解析”,在日常操作中,相信很多人在Go语言怎么实现JSON解析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Go语言怎么实现JSON解析”的疑惑有所帮助!接下来,请跟...
    99+
    2023-06-30
  • C语言中栈的两种实现方法详解
    目录一、顺序栈二、链式栈总结一、顺序栈 #include<stdio.h> #include<stdlib.h> #define maxsize 64 ...
    99+
    2024-04-02
  • C语言详解实现字符菱形的方法
    目录前言1.定义stdio.h头文件2.定义主函数3.定义行数-单数4.得出分割行数5.定义字符6.初始化打印字符数与打印空白数7.循环打印菱形8.打印上部分9.打印剩下部分10.完...
    99+
    2024-04-02
  • C语言实现读取CSV文件的方法详解
    1、每一次只能读取同一种数据类型,不能读取字符串。 2、第次读取会返回一个 CSV数据结构,有源数据和二维数组,行列数信息 3、可以转换二维数组,但总大小不能变 123.csv M...
    99+
    2022-12-21
    C语言读取CSV文件 C语言读取CSV C语言 CSV
  • Oracle解析复杂json的方法实例详解
    问题背景:          当前在Oracle数据库(11G之前的版本)解析json没有可以直接使用的系统方法,网上流传的P...
    99+
    2024-04-02
  • 实例详解esp8266解析json数据的方法
    #include <ArduinoJson.h> void setup() { Serial.begin(115200); Serial.println("这里用...
    99+
    2024-04-02
  • C语言详解strcmp函数的分析及实现
    目录1.函数介绍1.1.函数接口1.2.函数分析1.3.函数的简单使用1.4.函数使用结果分析2.库函数strcmp源代码2.1.库函数源代码2.2.库函数分析3.模拟实现 strc...
    99+
    2024-04-02
  • Go 语言 json解析框架与 gjson 详解
    目录1. 快速使用2. Get() 返回的 Result 结构体3. 键路径4. json 数组遍历5. 其他前言: JSON 解析是我们不可避免的常见问题,在 Go 语言中,我们可...
    99+
    2024-04-02
  • C语言实现数组元素排序方法详解
    目录前言算法总结及实现优化算法前言 在实际开发中,有很多场景需要我们将数组元素按照从大到小(或者从小到大)的顺序排列,这样在查阅数据时会更加直观,例如: 一个保存了班级学号的数组,排...
    99+
    2023-02-11
    C语言数组元素排序 C语言数组元素 C语言数组排序
  • C语言实现BF算法案例详解
    BF算法:        BF算法即暴风算法,是普通的模式匹配算法。BF算法的思想:将目标串S的第一个字符与模式串T的第一个字符进行匹配,若相...
    99+
    2024-04-02
  • Go语言实现ssh&scp的方法详解
    目录前言连接远程服务器并执行命令(ssh)拷贝远程服务器文件到本地(scp)简单封装下前言 最近遇到一个临时需求,需要将客户环境中一个服务每天的日志进行一系列复杂处理,并生成数据报表...
    99+
    2024-04-02
  • C#实现读写CSV文件的方法详解
    目录CSV文件标准文件示例RFC 4180简化标准读写CSV文件使用CsvHelper使用自定义方法总结项目中经常遇到CSV文件的读写需求,其中的难点主要是CSV文件的解析。本文会介...
    99+
    2024-04-02
  • C语言实现随机读写文件的函数详解
    目录1.fseek2.ftell3.rewind总结在上一篇博客中,我详细讲解了如何使用C语言顺序读写文件。所谓顺序读写,就是按照顺序,挨个挨个的读或者写,换句话说,我必须先读第一个...
    99+
    2023-05-14
    C语言随机读写文件 C语言读写文件 C语言 文件
  • C语言 队列的实现全解析
    目录队列的实现基本概念创建结构体初始化结构体销毁队列结构体入队出队判断队列是否为空访问对头的值访问队尾的值返回队列的长度Queue.hQueue.cTest.c队列的实现 基本概念 ...
    99+
    2024-04-02
  • C语言printf详细解析
     1.类型: 表示输出类型的格式字符      格式字符意义 a         ...
    99+
    2022-11-15
    C语言 printf
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作