用C写的一个简易JSON Parser
初来乍到的一学期实在是无聊,于是在百团大战中加了计算机协会,就认识了几个计算机和软件专业的人。看见一软件同学在空间上转发的C语言期末项目,顿时生了兴趣。代码是春节期间写完的,可惜这个博客被搁置了太久,现在把代码贴上来,也不算过分吧。
作业的具体内容是:老师给定一个头文件 json.h ,包含了 json 数据结构的定义以及一些相关函数的声明,任务就是实现这些函数,最后提交通过学校的自动化测试。我不是软件的学生,自然没有这个权利,不过手工检验了一下,貌似还没有太大问题。只是最近写一个 web 项目的时候,把其间一个比较“庞大”的 json 文件(也才4KB!)当作测试材料,结果程序直接崩溃了;再截取一小部分,又能运行了。难道是字符串读写复制操作太多?可貌似连 fopen 函数都调用失败了,搞不懂。
老师们给的头文件想必是由 cJSON 的头文件修改而来的,json结构体的定义如下:
typedef struct JSON { int type; /* The type of the item, as above. */ char *valuestring; /* The item's string, if type==JSON_STRING */ int valueint; /* The item's number, if type==JSON_TRUE||JSON_FLASE; or quantity of members, if type==JSON_ARRAY||JSON_OBJECT */ double valuedouble; /* The item's number, if type==JSON_NUMBER */ // the following are created by me struct JSON *head; /* Head of array, if type==JSON_ARRAY||JSON_OBJECT */ struct JSON *last; /* Previous member, if this belongs to an array or object */ struct JSON *next; /* Next member, if this belongs to an array or object */ char *name; /* Name of member, if this belongs to an object */ } JSON;
函数众多就不一一列举了,有几个实现起来相对复杂的:
C语言中数值和字符串的相互转换
整数->字符串可以使用stdio.h中的sprintf函数,有的人可能会说到itoa,但其实itoa不是C标准库的函数,是微软自己添加的。
sprintf的原型是:
int sprintf ( char * str, const char * format, ... );
和printf用法相同。当然也可用于其它类型如double。
例:
char str[20]; int s = 1000000; sprintf(str, "%d", s);
字符->整数同样使用的也是stdio.h中的sscanf函数,stdlib.h中也有atoi和strtol可以进行转换。
int sscanf ( const char * str, const char * format, ... ); int atoi ( const char * str ); long int strtol ( const char * nptr, char ** endptr, int base);
sscanf和atoi的用法都很简单。值得一提的是strtol这个函数。第一个参数是源字符串,第二个参数用于接收非法字符串的首地址,第三个参数是转换后的进制。