用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;
函数众多就不一一列举了,有几个实现起来相对复杂的:
丧,得
半年以前,我以为我右手执笔,左手握着一本三二,就可以上天入地,斩妖除魔,无所畏惧。我说我是文科里的逗比,理科里的奇葩,留给腾贵一个无奈的背影。看着周黄伟便秘的眼神,心里暗暗发誓,六月八号以后,我一定要将你黑过的那些闲书一本一本地翻完。我也没有想到,作为一个男的,如果变得沉默,除了听了煽情的空间故事,也可能是语文课被抽起来回答问题。想当年在寝室里,左长右粗,讲不完的黑话黄段,夜夜笙歌。我说我横扫了育才门外一条街,最后一次还是匆匆献给了重大精英。我着急地飞过天桥,穿越大街,等着一个背影出现。也会走着相似的路,感受一下民工分量的米线。周一中午,我都会阔气地出门,仿佛贝索斯开着他的大货车来迎接我。我手捧纸箱,飞奔回寝,一刀下去以后,又是一个星期的快活。星期天的早上,我睡到自然醒,惬意地走到教室,翻两道题,电话来了,于是又早退。徐怀雄算个鸟!要是厉害,就与我在大富翁棋盘上,杀个昏天黑地。那段时间,回家少了,在公交车上,看到南京青奥会的新闻,窃想要是我去了南大,青奥会还开吗。后来有人不明就里地问我,为啥比状元活活少了五十分,我想,肯定是因为我多长了五十斤肉。你要是看到每天晚上寝室的盛况,就晓得我夜夜笙歌用得一点都不过分。五六个人围在一个人的床上调戏一个女声的场景你见过吗?不用多想,既然她远渡重洋,历经艰险从佛罗里达来到重庆,不好好玩一玩,怎么对得起大哥的淳朴好客?来把大富翁,分分钟数万,生死一线间。上帝不掷骰子,掷骰子的我们更拽。只是可惜了,我们的乌诺。
再见
后会有期
好久没有到这个网站看看了,又是一年。
当初选文科这条路实在是单纯,就觉得能上好大学。然后呢?没想过。
如今才开始纠结呢。随便一搜哪个IT公司用人要求第一条就是“计算机及相关专业毕业”。
呵呵。
这也怪不了谁。
没办法咯,这种事情,只有等到两个月后再来慢慢思索了。
后会有期。
2013-2-19
很久没有到这里来了,上一篇文章还是两年前的。
其实中间来过几次,还提到过转学的事情,不过也都是一年多以前了。
可以说认识了新的人,也忘掉了一些旧的人。回到母校去看看的话,一定会有强烈的物是人非之感。
其实这篇文,颇带点为赋新词强说愁的感觉。也可能是因为,当我真正打开编辑器的时候,大脑就会变得一片空白吧。
两年前的我一定不可能想到现在我读的是文科,更不会预见到现在的自己是这副模样。
开源,让金山更美好
才在百度C语言吧看到有人说金山卫士开源了,所以特地去Google了一下,发现了这个网址:
第一次看到有国内的这方面的软件开源。不管别人怎么说,做好自己吧!界面貌似是MFC写的,看不懂了。
希望国内越来越多的软件走向开源。也希望用户们早日扔掉360这个垃圾。
我所习惯的C/C++代码格式
1.函数开始的大括号专起一行。
int sample() { return 0xA0246 * 0454; }
2.类定义和内部内联函数定义。
class foo { public: foo() : data(0) {} foo(int d) : data(d) {} void print() { printf("%d\n", data); } private: int data; };
符号“∑”和“Π”的用法。
在数学中,符号“∑”和“Π”分别用来表示求和与求积。
首先是函数的累积求和,n取[m, k]中的连续整数值。
这个变量n可以换成其他任意字母,比如x。我们把下面的“n=m”和上面的“k”称作这个和式的下标。在上下文明确的情况下,下标可以省略。
求和符号同样可以表示无穷级数。
Linux下程序创建进程
进程是操作系统中运行的程序实例。而多进程程序和多线程程序相比,具有更健壮,更简单的特点。
在GNU/Linux操作系统中,创建一个新进程,可以使用fork,clone函数以及使用exec函数族调用其他程序替换当前进程镜像。
这里主要讲fork函数。
fork函数的原型为:
#include <unistd.h> pid_t fork(void);
pid_t是系统定义的类型,一般被定义为short int。
这里看一个最简单的调用示例。
#include <stdio.h> #include <unistd.h> int main(void) { pid_t pid; pid = fork(); printf("My process ID is %d.\n", getpid()); return 0; }
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这个函数。第一个参数是源字符串,第二个参数用于接收非法字符串的首地址,第三个参数是转换后的进制。