欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語言實現(xiàn)手寫JSON解析的方法詳解

 更新時間:2022年09月16日 14:14:08   作者:胡安民-獨行者  
JSON(JavaScript?Object?Notation)是一種輕量級的數(shù)據(jù)交換格式,用來傳輸屬性值或者序列性的值組成的數(shù)據(jù)對象。本文將利用C語言實現(xiàn)手寫JSON解析,感興趣的可以了解一下

什么是JSON

JSON(JavaScript Object Notation)是一種輕量級的數(shù)據(jù)交換格式,用來傳輸屬性值或者序列性的值組成的數(shù)據(jù)對象。

JSON是JavaScript的一個子集。

具有良好的可讀性和便于快速編寫的特性。

JSON是獨立于語言的文本格式,并且采用了類似C語言家族的一些習(xí)慣。

JSON數(shù)據(jù)格式與語言無關(guān),是目前網(wǎng)絡(luò)中主流的數(shù)據(jù)傳輸格式之一,使用率幾乎為99%。

JSON支持的數(shù)據(jù)類型

JSON里面的數(shù)據(jù)以一種鍵值對的方式存在,即“key”:“value” 類型可以是數(shù)據(jù)類型中的任意一種:

JSON語法規(guī)則

JSON的語法規(guī)則非常簡單,使用

大括號——{}

中括號——[]

逗號——,

冒號——:

雙引號——“” (一般可以不需要)

JSON的解析

在解析JSON是我們會遇到兩種情況,其一是解析大括號——{}類型,其二是解析中括號類型——[],以及這兩種類型的組合模式。

JSON基本語法

對象類型(Object)

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

數(shù)組類型(Array)

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

對象組合形

{
    "name" : "佩奇" ,  
    "age" : "8",
    "friend" :[{"name" : " 喜羊羊 " , "age" : "5"} , {"name" : " 懶羊羊 " , "age" : "6"}]
    //對象類型嵌套數(shù)組類型,數(shù)組類型嵌套對象類型
}

數(shù)組組合型

[ [{"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

實現(xiàn)文件

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

#include "json.h"


//轉(zhuǎn)換字符串為JSON_先進行占位符替換
static char *str_to_json_placeholder(char *string, CharHashMap *map, CharHashMap *list) {
    //判斷是否有[],如果有那么提取出來,并且將位置上的內(nèi)容替換為 @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;
    //判斷是否有{},如果有那么提取出來, 并且將位置上的內(nèi)容替換為@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")) {
        //替換參數(shù)為原來的值
        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,如果有那么就繼續(xù)替換
    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;
}


//將字符串?dāng)?shù)組格式[1,2,3]或者[{a:b,c:d},{a:b,c:d}]轉(zhuǎn)換為List  ,(沒有任何格式驗證,全靠自己規(guī)范編寫)
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},轉(zhuǎn)換為hashMap  ,(沒有任何格式驗證,全靠自己規(guī)范編寫)
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轉(zhuǎn)換為json對象{a:b,c:d,v:[1,2],f:{a:b,c:d}} ,(沒有任何格式驗證,全靠自己規(guī)范編寫)
char *map_to_json_str(CharHashMap *pMap) {
    if (pMap == NULL) {
        return NULL;
    }
    char *string = str_create("{");
    int len = pMap->size;
    //創(chuàng)建迭代器
    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轉(zhuǎn)換為json數(shù)組格式[1,2,[1,2,3]]或者[{},{}] ,(沒有任何格式驗證,全靠自己規(guī)范編寫)
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;
}

//判斷是否是數(shù)組
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;
}

到此這篇關(guān)于C語言實現(xiàn)手寫JSON解析的方法詳解的文章就介紹到這了,更多相關(guān)C語言 JSON解析內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 淺談C++為什么非要引入那幾種類型轉(zhuǎn)換

    淺談C++為什么非要引入那幾種類型轉(zhuǎn)換

    這篇文章主要介紹了C++為什么非要引入那幾種類型轉(zhuǎn)換,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • C語言指針之必須要掌握的指針基礎(chǔ)知識

    C語言指針之必須要掌握的指針基礎(chǔ)知識

    這篇文章主要介紹了C語言指針必須要掌握的基礎(chǔ)知識,文中實例講解的很清晰,有不太懂的同學(xué)可以研究下,希望能夠給你帶來幫助
    2021-09-09
  • 使用C語言解決字符串匹配問題的方法

    使用C語言解決字符串匹配問題的方法

    這篇文章主要介紹了使用C語言解決字符串匹配問題的方法,包括一道實例練習(xí)題,需要的朋友可以參考下
    2015-08-08
  • C++中for auto的用法及說明

    C++中for auto的用法及說明

    這篇文章主要介紹了C++中for auto的用法及說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • C++11新特性之自定義字面量

    C++11新特性之自定義字面量

    這篇文章主要介紹了C++11新特性之自定義字面量的相關(guān)資料,幫助大家更好的學(xué)習(xí)c++,感興趣的朋友可以了解下
    2020-08-08
  • 詳解C語言如何執(zhí)行HTTP GET請求

    詳解C語言如何執(zhí)行HTTP GET請求

    在現(xiàn)代互聯(lián)網(wǎng)時代,網(wǎng)絡(luò)數(shù)據(jù)的獲取和分析變得越來越重要,本文我們將使用C語言和libcurl庫來編寫一個簡單的網(wǎng)絡(luò)爬蟲,以執(zhí)行HTTP GET請求并獲取淘寶網(wǎng)頁的內(nèi)容,感興趣的可以了解下
    2023-11-11
  • 詳解C/C++中const關(guān)鍵字的用法及其與宏常量的比較

    詳解C/C++中const關(guān)鍵字的用法及其與宏常量的比較

    簡單的說const關(guān)鍵字修飾的變量具有常屬性,也就是說它所修飾的變量不能被修改,下文給大家介紹C/C++中const關(guān)鍵字的用法及其與宏常量的比較,需要的朋友可以參考下
    2017-07-07
  • mfc入門教程之實現(xiàn)一個簡單的計算器

    mfc入門教程之實現(xiàn)一個簡單的計算器

    這篇文章主要介紹了mfc入門教程,手把手教你如何開發(fā)一個簡單的計算器,需要的朋友可以參考下
    2019-04-04
  • C++語言const 關(guān)鍵字使用方法圖文詳解

    C++語言const 關(guān)鍵字使用方法圖文詳解

    在類中,如果你不希望某些數(shù)據(jù)被修改,可以使用const關(guān)鍵字加以限定。const 可以用來修飾成員變量、成員函數(shù)以及對象
    2020-01-01
  • 深入了解C++的多態(tài)與虛函數(shù)

    深入了解C++的多態(tài)與虛函數(shù)

    這篇文章主要為大家詳細(xì)介紹了C++多態(tài)與虛函數(shù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-07-07

最新評論