我想解析一个如下所示的文件格式:
SECTION Foo
10
END
我尝试使用以下代码进行解析。如果出现解析错误,它应返回1:
int main()
{
char str[100];
int n;
int nr1 = scanf("SECTION %s", str);
if (nr1 != 1) return 1;
int nr2 = scanf("%d", &n);
if (nr2 != 1) return 1;
int nr3 = scanf("END");
if (nr3 != 0) return 1;
printf("OK! %s %d\n", str, n);
return 0;
}
但是,即使在标准输入中键入OK!
之前,END
消息也会显示。我真正想要的是检测stdin中出现的下一个字符串是否为END
,否则返回错误代码。有没有办法可以修改scanf("END")
行来实现这个目标?
现在,我能想到的唯一方法是使用%s
scanf后跟strcmp
,但为此必须引入额外的临时变量似乎不够优雅。
答案 0 :(得分:4)
要使用scanf()
并确定在最后一个指令(即使是0个说明符)之后是否按需要扫描,请使用"%n"
。这记录了扫描的偏移 - 如果扫描到达该点。
int n = 0;
scanf("END%n", &n);
if (n > 0) {
// Scan made it past "END"
Success();
} else {
Failure();
}
还是最好用fgets()
读取行,然后解析/扫描字符串。使用scanf()
很难应对意外的输入。
请注意scanf("SECTION %s", str);
缺少宽度限制
建议int nr1 = scanf("SECTION %99s", str);
答案 1 :(得分:0)
你不能使用scanf()
,因为它会返回解析的令牌数,当没有解析令牌时,就意味着你无法告诉失败的成功。
这不是什么大问题,因为无论如何使用scanf()
进行解析并不是一个好主意。相反,您应该简单地标记您的文件(在您的情况下,通过换行符然后是空格),并分析标记。这意味着使用fgets()
,strcmp()
,sscanf()
,strtol()
等。
或者像ANTLR一样使用解析器生成器。