大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全家桶1年46,售后保障稳定
C语言json格式校验
最近用到json格式数据传输信息,在C语言中使用cjson解析json字符串,若json格式不正确,会使整个进程直接挂掉。想到能否在解析前先进行格式校验,通过后再解析,查找资料,网上有现成源码,网址:http://www.json.org/JSON_checker/
主要用到两个文件JSON_checker.c和JSON_checker.h,具体用法可以参考main.c。这里参考了博客:C语言如何检测json格式的数据合法性 中的用法,并加以改进。
在官网中提供了json检查的测试文件,但没有包含中文的,这里添加了一个中文测试文件,如下:
{
"JSON 测试 pass4": {
"Chinese": "中文测试.",
"这是pass4测试": "中文中文."
}
}
main.c
#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 failed\n", 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 check\n", abyFile);
//解析json_src_string
//to do
}
else
{
printf(" %s fail check\n", 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 failed\n", 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 check\n", abyFile);
//解析json_src_string
//to do
}
else
{
printf(" %s fail check\n", 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:
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 error\n");
return -1;
}
}
if (0 == JSON_checker_done(jc))
{
fprintf(stderr, "JSON_checker_end: syntax error\n");
return -1;
}
return 0;
}
main.c中的replace_character函数如下:
/* 将中文字符替换为'*' 用于json字符串合法性检查 instr: 原字符串(用来解析) outstr: 替换后字符串(用来检查) */
int replace_character(char *instr, char* outstr)
{
if (instr == NULL)
{
printf("No string buf...\n");
return -1;
}
while(*instr != '\0')
{
//acsll范围00-7F
if (((*instr) < 0x00) || ((*instr) > 0x7F))
{
*outstr++ = '*';
instr++;
}
else
{
*outstr++ = *instr++;
}
}
return 0;
}
因为这里会把输入中包含中文的字符串按字节替换为 “*”,因此解析时候还得用原字符串。如果确认json字符串中不含有中文,则不需要调用replace_character,直接调用json_checker(json_src_string)即可。
将以上两个文件和main.c通过Makefile一起编译,遍历test中的测试文件,测试结果如下:
JSON_checker_char: syntax error
test/fail1.json fail check
.
.
.
JSON_checker_end: syntax error
test/fail32.json fail check
JSON_checker_char: syntax error
test/fail33.json fail check
test/pass1.json pass check
test/pass2.json pass check
test/pass3.json pass check
test/pass4.json pass check
test/pass5.json pass check
以上源码包括test文件打包下载:c语言json格式校验代码
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/207456.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...