使用 fscanf 读取时包含换行符

Include newline character when reading with fscanf

如何在使用 fscanf() 逐字读取文件时读取(n 个可选的)换行符?

我知道我可以使用 fgets() + strtok(),但我的程序特别需要 fscanf().

我试过以下方法:

fscanf(fp, "%s%[\n]+", buf);

但是一点用都没有。

您可以使用此转换格式使用和忽略单个换行符:%*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