用C写的json解析工具(逐步完善中)

首先是定义json结构和接口

#ifndef CJSON_CJSON_H
#define CJSON_CJSON_H

#include <basetsd.h>

typedef enum type
{
    STRING_1,
    OBJECT_1,
    BOOL_1,
    ARRAY_1,
    INTEGER_1,
    DOUBLE_1
}Type;

typedef struct cjson
{
    /*
     * 字节对齐稍后再算
     */
    struct cjson *next;
    struct cjson *prev;
    Type t;
    char *key;
    struct cjson *object; // 对象的首地址
    unsigned int object_length;
    struct cjson **array; // 数组首地址
    unsigned int array_length;
    char *string;
    long long valueInt;
    double valueDouble;
    int valueBool;
}Cjson;

/*
 *  json解析入口,使用完毕请及时释放
 */
Cjson* jsonParser(char *s);
/*
 * 创建一个新的cjson节点,并初始化
 */
static Cjson* createNewNode();
/*
 * 将数组拆分成二维数组
 */
static unsigned int getRow(char *s);
Cjson **splitArray(char *s, unsigned int *length);
/*
 *  在所有键值中寻找key,并返回key所对应的cjson
 */
Cjson *cjson_find(Cjson *root, char *key);
/*
 * 假如json 以数组为组成结构,返回第index个数组
 */
Cjson *cjson_fingArray(Cjson *root, int index);
/*
 * 计算cjson总长度,由于末尾没有逗号也会被认为有逗号,所以会比原始长度大
 */
static unsigned int cjson_all_length(Cjson *root);
/*
 * 将cjson封装字符串
 */
static void packing(Cjson *root, char **buffer, char *numberBuffer);
/*
 * 封装入口 cachelength 缓冲内存大小,如果小于零,程序会自行计算大小,使用完毕请及时释放
 */
char *cjson_toString(Cjson *root, unsigned int cacheLength);
/*
 * 删除整张或部分表,这取决于root
 */
void free_all_cjson(Cjson *root);
/*
 * 1表示删除成功,0表示失败,
 */
int free_cjsonByKey(Cjson *node, char *key);

Cjson *createRoot();

#endif //CJSON_CJSON_H

然后是辅助工具的定义
内存申请工具

#ifndef CJSON_MEMERY_APPLY_H
#define CJSON_MEMERY_APPLY_H
char* createArray(const unsigned int length);
Cjson **createJsonArrayPointer(const unsigned int length);
double* createDouble(const unsigned int length);
long long* createInteger(const unsigned int length);

#endif //CJSON_MEMERY_APPLY_H

计算数字长度

unsigned int getIntegerLength(long long l);
unsigned int getDoubleLength(double d);

json键值的分析工具

#ifndef CJSON_STRING_TOOLS_H
#define CJSON_STRING_TOOLS_H


/*
 * 判断类型,分发,返回结果
 */
void parser(char **c_ptr, Type *type, void **content);

static void parseValue(char **value, Type *t, void **content);
static void parseString(char **value, void **content);
static void parseObject(char **value, void **content);
static void parseArray(char **value, void **content);
static void parseBool(char **value, void **content);
#endif //CJSON_STRING_TOOLS_H

下面是代码。

// string_tools.c
//
//
#include "cjson.h"
#include "string_tools.h"
#include "memery_apply.h"
#include <stdlib.h>
#include <stdio.h>

/*
 * 截取字符串,判断类型,分发,返回结果
 * c_ptr:游标指针
 */
void parser(char **c_ptr, Type *t, void **content)
{
    if('"' == **c_ptr)
    {
        *t = STRING_1;
        parseString(c_ptr, content);
    }
    else if('[' == **c_ptr)
    {
        *t = ARRAY_1;
        parseArray(c_ptr, content);
    }
    else if('{' == **c_ptr)
    {
        *t = OBJECT_1;
        parseObject(c_ptr, content);
    }
    else if('t' == **c_ptr || 'f' == **c_ptr)
    {
        *t = BOOL_1;
        parseBool(c_ptr, content);
    }
    else if(**c_ptr <= '9' && **c_ptr >= '0')
    {
        parseValue(c_ptr, t, content);
    }
}

static void parseValue(char **value, Type *t, void **content)
{
    *t = INTEGER_1;
    unsigned int content_length = 0;
    char *temp = *value;
    char *temp1 = *value;
    while (*temp != ',' && *temp != ']' && *temp != '}')
    {
        content_length++;
        temp++;
    }
    temp = createArray(content_length);
    int tempCursor = 0;
    while (*temp1 != ',' && *temp1 != ']' && *temp1 != '}')
    {
        if(*temp1 == '.')
        {
            *t = DOUBLE_1;
        }
        temp[tempCursor] = *temp1;
        temp1++;
        tempCursor++;
    }
    temp[tempCursor] = '\0';
    (*value) += content_length;
    if(*t == DOUBLE_1)
    {
        double *i = createDouble(1);
        *i = strtod(temp, NULL);
        free(temp);
        *content = (void*)i;
    }
    else
    {
        long long *i = createInteger(1);
        *i = strtol(temp, NULL, 10);
        free(temp);
        
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值