我的问题似乎很简单,但我在谷歌上找不到答案。
我想知道while (fscanf(inFile, "%[^ n] ", string) != EOF)
是做什么的。我正在尝试使用上面的命令从文件中读取字符串。
然而,我不确定这句话是做什么的,特别是%[^ n]
部分。我知道它会循环直到文件结束,但是"字符串"是一个数值还是其他值?另外,我该如何使用它?
例如,对于一个句子"I like trees",字符串值等于什么?
提前谢谢。
%[^ n]
告诉fscanf
读取除n
和space
以外的所有字符
注意插入符号^
后面的空格和fscanf
的格式字符串"%[^ n] "
后面的空格。
fscanf(inFile, "%[^ n] ", string)
上面的语句意味着fscanf
将从流inFile
中读取并匹配任何不包含空格' '
或换行符'n'
的非空字符序列,并将它们写入到下一个参数string
的缓冲区指针中,然后读取并丢弃任意数量的(包括零)空白字符(即格式字符串中的尾随空格)。string
指向的缓冲区必须足够大,可以容纳任何这样的字符序列加上自动添加的终止空字节。如果缓冲区不够大,那么fscanf
将调用未定义的行为,并且很可能由于段错误导致程序崩溃。您必须通过指定最大字段宽度来防止它,该字段宽度应小于缓冲区长度以容纳终止的空字节。
fscanf
返回成功匹配和分配的输入项的总数,在本例中为1。当到达流inFile
中的文件结束时,它将返回EOF
。因此,while
循环条件意味着fscanf
将读取这样的字符序列并将其写入缓冲区string
,直到到达流inFile
中的文件末尾。
你应该改变你的while
循环为-
// assuming string is a char array
char string[100];
while(fscanf(inFile, "%99[^ n] ", string) == 1) {
// return value 1 of fscanf means fscanf call was successful
// do stuff with string
}
"%[^ n]"
基本上它匹配除了n
或' '
字符的所有内容。
您的fscanf
语句将从inFile
指向的文件中读取所有内容,然后将其读取的内容存储到名为string
的字符串中,该字符串应声明为char string[500]
(或类似的足够大的值)。每次成功读取一个字符,它就返回该字符。
现在,由于您需要一种在读取文件后退出while
循环的方法,因此您将fscanf
的返回值与EOF
的返回值进行比较,CC_34是特殊的文件结束字符。
while (fscanf(inFile, "%[^ n] ", string) != EOF)
有很大的问题。
格式字符串"%[^ n] "
由两个指令组成:"%[^ n]"
和" "
。
"%[^ n]"
是由一个扫描集组成的格式说明符。扫描集由除 ' '
和'n'
以外的所有char
组成。因此,fscanf()
查找扫描集中的1个或多个字符并将它们保存到string
。
"%[^ n]"
有两个问题:
1)如果遇到的第一个字符不在扫描集中,fscanf()
将字符解回inFile
,函数返回0。不再进行进一步扫描。因此,如果inFile
以' '
开头,代码在string
中不放任何东西,inFile
不进阶,后续代码设置为UB或无限循环!
2)保存在string
中的字符数是无限的。因此,如果inFile
开头的值大于扫描集中的sizeof(string)-1
char
,则会发生未定义行为。
" "
指令告诉fscanf()
使用0 或更多空白char
。如果inFile
的值为stdin
,这可能会令人困惑。在这种情况下,用户需要在 ' '
或'n'
之后输入一些非空白的。由于stdin
通常是行缓冲的,这意味着需要在scanf()
保存"abc"
并返回1之前输入"abcndefn"
之类的内容。"defn"
还在stdin
中
推荐:
char string[100];
while (fscanf(inFile, "%99s", string) == 1) {
...
}
"%99s"
将选择性地使用前导空白,然后使用最多99个非空白char
,附加通常的