我正在尝试使用fscanf解析文本(CSS)文件,并提取出与此模式匹配的所有语句:
@import“some / file / somewhere.css”;
为此,我设置了以下循环:
FILE *file = fopen(pathToSomeFile, "r");
char *buffer = (char *)malloc(sizeof(char) * 9000);
while(!feof(file))
{
// %*[^@] : Read and discard all characters up to a '@'
// %8999[^;] : Read up to 8999 characters starting at '@' to a ';'.
if(fscanf(file, "%*[^@] %8999[^;]", buffer) == 1)
{
// Do stuff with the matching characters here.
// This code is long and not relevant to the question.
}
}
这非常有效,因为文件中的第一个字符不是'@'。 (从字面上看,CSS文件中第一个'@'字符前的单个空格将使代码运行正常。)
但是如果CSS文件中的第一个字符是'@',那么我在调试器中看到的是无限循环 - 执行进入while循环,命中fscanf语句,但不输入'if '声明(fscanf失败),然后永远继续循环。
我相信我的fscanf格式化程序可能需要一些调整,但我不确定如何继续。对于为什么会发生这种情况的任何建议或解释?
谢谢。
答案 0 :(得分:2)
我不是scanf
模式语法的专家,但我对你的解释是:
'@'
字符的非空序列,然后';'
字符的非空序列所以是的,如果你的字符串以'@'
开头,那么第一部分就会失败。
我认为如果你用一些空格开始你的格式字符串,那么fscanf
会占用你数据字符串中的任何前导空格,即只是" %8999[^;]"
。
答案 1 :(得分:1)
Oli已经说过为什么fscanf失败了。由于故障是fscanf的正常状态,因此繁忙的循环不是fscanf故障的结果,而是缺少处理的结果。
即使您的格式正确(在您的特殊情况下),您也必须处理fscanf故障,因为您无法确定输入始终是否可以通过格式匹配。实际上,您可以确定存在比匹配输入更多的不匹配输入。
答案 2 :(得分:0)
您的格式字符串执行以下操作:
@
字符;
字符不幸的是,没有用于从用户定义的集合中读取“零个或多个”字符的格式说明符。
如果您不关心某行上的多个@include语句,可以将代码更改为读取单行(使用fgets),然后从中提取@include语句(如果第一个字符不相等) @
,您可以将当前格式字符串与sscanf一起使用,否则,您可以使用sscanf(line, "%8999[^;]", buffer)
)。
如果应该正确处理一行上的多个@include statemens,您可以使用getc
检查要读取的下一个字符,然后将其与ungetc
一起放回。