大家好,又见面了,我是你们的朋友全栈君
C语言json格式校验
最近用到json格式数据传输信息,在C语言中使用cjson解析json字符串,若json格式不正确,会使整个进程直接挂掉。想到能否在解析前先进行格式校验,通过后再解析,查找资料,网上有现成源码,网址:http://www.json.org/JSON_checker/
主要用到两个文件JSON_checker.c和JSON_checker.h,具体用法可以参考main.c。这里参考了博客:C语言如何检测json格式的数据合法性 中的用法,并加以改进。
在官网中提供了json检查的测试文件,但没有包含中文的,这里添加了一个中文测试文件,如下:
代码语言:javascript复制{
"JSON 测试 pass4": {
"Chinese": "中文测试.",
"这是pass4测试": "中文中文."
}
}
main.c
代码语言:javascript复制#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "JSON_checker.h"
/* 批量读取test下文件并检查json格式 */
int main()
{
int nRtn = 0;
FILE *fp;
int i;
int nStrLen;
char abyFile[16] = {
0};
char *json_src_string = NULL;
char *json_chk_string = NULL;
//错误文件检查
for (i = 1; i < 34 ; i )
{
sprintf(abyFile, "test/fail%d.json", i);
if ((fp = fopen(abyFile, "rb")) == NULL)
{
printf("open %s failedn", abyFile);
continue;
}
fseek(fp, 0, SEEK_END);
nStrLen = ftell(fp) 1;
json_src_string = (char *) malloc(sizeof(char) * nStrLen);
memset(json_src_string, 0, sizeof(char) * nStrLen);
json_chk_string = (char *) malloc(sizeof(char) * nStrLen);
memset(json_chk_string, 0, sizeof(char) * nStrLen);
fseek(fp, 0, SEEK_SET);
fread(json_src_string, nStrLen, sizeof(char), fp);
fclose(fp);
//替换中文字符为“*”
replace_character(json_src_string, json_chk_string);
nRtn = json_checker(json_chk_string);
if (0 == nRtn)
{
printf(" %s pass checkn", abyFile);
//解析json_src_string
//to do
}
else
{
printf(" %s fail checkn", abyFile);
}
free(json_src_string);
json_src_string = NULL;
free(json_chk_string);
json_chk_string = NULL;
memset(abyFile, 0, sizeof(abyFile));
}
//正确文件检查
for (i = 1; i < 6 ; i )
{
sprintf(abyFile, "test/pass%d.json", i);
if ((fp = fopen(abyFile, "rb")) == NULL)
{
printf("open %s failedn", abyFile);
continue;
}
fseek(fp, 0, SEEK_END);
nStrLen = ftell(fp) 1;
json_src_string = (char *) malloc(sizeof(char) * nStrLen);
memset(json_src_string, 0, sizeof(char) * nStrLen);
json_chk_string = (char *) malloc(sizeof(char) * nStrLen);
memset(json_chk_string, 0, sizeof(char) * nStrLen);
fseek(fp, 0, SEEK_SET);
fread(json_src_string, nStrLen, sizeof(char), fp);
fclose(fp);
//替换中文字符为“*”
replace_character(json_src_string, json_chk_string);
nRtn = json_checker(json_chk_string);
if (0 == nRtn)
{
printf(" %s pass checkn", abyFile);
//解析json_src_string
//to do
}
else
{
printf(" %s fail checkn", abyFile);
}
free(json_src_string);
json_src_string = NULL;
free(json_chk_string);
json_chk_string = NULL;
memset(abyFile, 0, sizeof(abyFile));
}
return 0;
}
main.c中的json_checker函数如下,格式正确返回0,否则返回-1:
代码语言:javascript复制int json_checker(const char *json_str)
{
JSON_checker jc = new_JSON_checker(20);
int len = strlen(json_str);
int tmp_i = 0;
for (tmp_i = 0; tmp_i < len; tmp_i )
{
int next_char = json_str[tmp_i];
if (next_char <= 0)
{
break;
}
if (0 == JSON_checker_char(jc, next_char))
{
fprintf(stderr, "JSON_checker_char: syntax errorn");
return -1;
}
}
if (0 == JSON_checker_done(jc))
{
fprintf(stderr, "JSON_checker_end: syntax errorn");
return -1;
}
return 0;
}
main.c中的replace_character函数如下:
代码语言:javascript复制/* 将中文字符替换为'*' 用于json字符串合法性检查 instr: 原字符串(用来解析) outstr: 替换后字符串(用来检查) */
int replace_character(char *instr, char* outstr)
{
if (instr == NULL)
{
printf("No string buf...n");
return -1;
}
while(*instr != '