使用fscanf()
逐字读取文件时,如何读取(n个可选的)换行符?
我知道我可以使用fgets()
+ strtok()
,但是我的程序特别需要fscanf()
。
我尝试了以下操作:
fscanf(fp, "%s%[\n]+", buf);
但这根本不起作用。
答案 0 :(得分:1)
您可以使用以下转换格式来使用和忽略单个换行符:%*1[\n]
。它最多消耗一条换行符并将其丢弃。请注意,如果有多个连续的换行符,则只会跳过第一个。还要注意fscanf()
将读取一个额外的字节以验证其是否匹配。如果不匹配,该字节将使用ungetc()
推回到流中。
如果您使用%*[\n]
,则fscanf
将继续读取流,直到它获得与换行符不同的字节或到达文件末尾为止,这将在处理来自终端的交互式输入时引起令人惊讶的行为。
您的代码fscanf(fp, "%s[\n]", buf);
导致未定义的行为,因为您没有为换行符提供目标数组。此外,它还有另一个缺陷,因为您没有指定要存储到buf
中的最大字节数,从而导致长字输入出现不确定的行为。
尝试一下:
char buf[100];
if (fscanf(" %99s%*1[\n]", buf) == 1) {
printf("read a word: |%s|\n", buf);
} else {
printf("no more words\n");
}
如果要在缓冲区中包含换行符,则需要将其存储到变量中并手动添加:
#include <stdio.h>
#include <string.h>
int main() {
for (;;) {
char buf[100];
char nl[2] = "";
int n = fscanf(stdin, " %98s%1[\n]", buf, nl);
if (n > 0) {
strcat(buf, nl);
printf("read a word: |%s|\n", buf);
} else {
printf("no more words\n");
break;
}
}
return 0;
}
输入:
Hello word
I am ready
输出:
read a word: |Hello|
read a word: |word
|
read a word: |I|
read a word: |am|
read a word: |ready|
no more words