我的工作是从文件中读取文本的程序,并解析文本文字和操纵它们,我就是那样的使用的fscanf解析的话我怎么能检查时,我跳过线
的fscanf解析当while (fscanf (fp, " %32[^ ,.\t\n]%*c", word) == 1)
{
/*manipulate the text word by word
}
我想要写相邻的,我觉得字,其中线我发现她
有没有办法,我可以检查,当我下移一行
使用功能的fscanf当的方法吗?
我的工作是从文件中读取文本的程序,并解析文本文字和操纵它们,我就是那样的使用的fscanf解析的话我怎么能检查时,我跳过线
的fscanf解析当while (fscanf (fp, " %32[^ ,.\t\n]%*c", word) == 1)
{
/*manipulate the text word by word
}
我想要写相邻的,我觉得字,其中线我发现她
有没有办法,我可以检查,当我下移一行
使用功能的fscanf当的方法吗?
最稳健的建议是使用fgets()
或许POSIX getline()
读线,然后考虑使用 sscanf()
解析每一行。您可能需要考虑how to use sscanf()
in a loop。还有许多其他选项可用于解析该行而不是sscanf()
,例如strtok_r()
或较不理想的strtok()
- 或者在Windows上,strtok_s()
; strspn()
, strcspn()
, strpbrk()
;和其他不规范的功能。
如果您认为必须使用fscanf()
,那么您可能需要捕获尾随上下文。这方面的一个简单的版本是:
char c;
while (fscanf(fp, " %32[^ ,.\t\n]%c", word, &c) == 2)
…
这抓住了单词后,假设有一个。如果您的文件没有以换行符结尾,则可能会丢失一个单词。错过换行也很容易。例如,如果行在换行符之前以句号结束(句号),则c
将保存.
,换行符将在下一次迭代循环中跳过。你可以克服用:
char s[33];
while (fscanf(fp, " %32[^ ,.\t\n]%32[ ,.\t\n]", word, s) == 2)
…
注意格式字符串的长度必须大于变量声明的长度少一个!
成功调用fscanf()
后,字符串s
可能包含多个换行符和空格等。 fscanf()
函数大多不关心换行符,并且如果s
的扫描集是数据文件中的内容,它将在一行中读取多个换行符。
如果你明确地从fscanf()
捕捉状态,可以是,没有一个换行符(或者一个标点符号)结尾的文件,或引起其他问题更加敏感:
char s[33];
int rc;
while ((rc = fscanf(fp, " %32[^ ,.\t\n]%32[ ,.\t\n]", word, s)) != EOF)
{
switch (rc)
{
case 2:
…proceed as normal, checking s for newlines.
break;
case 1:
…probably an overlong word or EOF without a newline.
break;
case 0:
…probably means the next character is one of comma or dot.
…spaces, tabs, newlines will be skipped without detection
…by the leading space in the format string.
break;
default:
assert(0);
break;
}
}
如果你开始关心约!
,?
,;
,:
,'
或"
字符 - 更不用说(
和)
- 生活变得更加复杂依然。事实上,在这一点上,sscanf()
的替代品开始看起来好多了。
这是很难正确地使用scanf()
家庭的功能。他们只是新手的工具,至少一旦你开始需要做任何复杂的事情。你可以看看A beginner's guide to not using scanf()
,其中包含很多有价值的信息。我不完全相信最后几个应该是防弹用途scanf()
的例子。 (正确使用sscanf()
会稍微简单一些,但是您仍然需要了解详细信息。)
与fgets()
然后读线使用sscanf
解析它们:
char buff[1024];
int lineno = 0;
int offset = 0;
while (fgets(buff, 1024, fp)) {
lineno++;
offset = 0;
while (sscanf(buff + offset, " %32[^ ,.\t\n]%*c", word) == 1)
{
/* manipulate the text word by word */
}
}
在第二环路必须增加缓冲器,以便正确地解析线适当偏移。为此,例如,您可以使用%n
来获取读取字节。
但请注意[在循环中使用'sscanf()'](http://stackoverflow.com/questions/3975236/how-to-use-sscanf-in-loops)。 –
谢谢,我补充说。 @JonathanLeffler –
'fscanf'不区分行,实际上大多数格式说明符都忽略所有空格。尝试使用'fgets'来读取每行,然后使用字符串分割函数。 –
...例如'strsep'或'strtok'及其派生词,如果你想分析单词。 –
'fscanf(fp,“%32 [^,。\ t \ n]%* c”,单词)'在不同的地方跳过''\ n'':领先''''也许''* c“' 。使用'fgets()'来读取_line_。 – chux