我正在尝试用C解析输入JSON文件,文件内容如下:{"version":"0.1","type":"tracbuf:e", "userid":0, "method":"udpbuf:-paris", "src":"10.20.6.191"buf:, "dst":"8.8.8.8", "sport":41buf:687, "dport":33435, ...
输入文件非常大,我想读取每一行并解析读取行,即分别分离键值对,并且行和键值字段的长度是任意的。
我知道fscanf()
可以正常使用。但我想使用一些带有边界保护的函数,例如fgets()
。但我不太确定在这种情况下如何使用fgets(),因为它会读取' n'缓冲区中的字节,包括新行,制表符空间和blankspace('')
。但是我希望能够在遇到空格/制表符空格/换行字符时解析读取字符,然后再读取其他行。
请注意,fscanf()
可以与strtok()
一起执行此操作 - 它会与每个空格/新行一起中断。但遗憾的是,它不允许在缓冲区上使用边界。
我该怎么办?
更新编辑:
以下方法有效。在每个条件中,我需要调用strtok并进行大约6次比较。但我想知道这是否可以做得更好。
while(fscanf(fp, "%100s", buf) != EOF)
{
token=strtok(buf,":-");
while(token!=NULL)
{
if(strcmp(token,"\"src\"")==0)
{
head[trace_count]=(HEADER*) malloc(sizeof(HEADER));
token=strtok(NULL,":{,}])");
strcpy(head[trace_count]->src_ip,token);
}
else if(strcmmp(...))
{
}
...
}
答案 0 :(得分:1)
由于行可以是任何长度,因此在将行读入缓冲区时总是会遇到问题。缓冲区可能永远不会足够大。唯一的方法是通过字符处理。以下是一个简单的基本语法分析器。根据需要进行调整:
void example(FILE *fin)
{
char c, token[MAX_TOKEN], tokval[MAX_SVAL], *s= token;
int instr= FALSE; // track whether we are in a string
int intok= TRUE; // track whether we are in a token name or a value
while ((c=fgetc(fin)) != EOF)
{
if (instr) {
if (c=='"')
{*s='\0'; instr= FALSE;}
else *s++ = c;
}
else switch (c) {
case '"': instr= TRUE; break;
case '{': /* open: whatever you want to do*/ break;
case '}': /* close: whatever you want to do*/ break;
case ':': if (intok) {*s= '\0'; s= tokval; intok= FALSE; /* have token name now*/} else *s++ = ':'; break;
case ',': if (!intok) {*s= '\0'; s= token; intok= TRUE; /* have a pair now */} else *s++ = ','; break;
case ' ': case '\t': case '\n': case '\r': break;
default: *s++ = c;
}
if (intok)
{if (s > token+MAX_TOKEN-2) error("token name too long");}
else {if (s > tokval+MAX_SVAL-2) error("token value too long");}
}
}