c - 使用 fscanf 读取时包括换行符

标签 c file scanf stdio

如何在使用 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

关于c - 使用 fscanf 读取时包括换行符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52728913/

相关文章:

c - 如何从程序本身获取指向特定可执行文件部分的指针? (也许与 libelf)

c - 关于 C 指针的最后一件事 : confused about what this snippet of code will do?

c - 入口点在正确的地方吗?

vb.net - 加密/解密文件出错

c++ - 是否为get_time定义了重复赋值?

c++ - 使用 libpcap 读取数据包

编译错误 - 从文件中读入

algorithm - Intel hex 文件中任意大小的填充模式

python - 在Python中读取格式化的多行

c - 可以为 scanf ("%x"传递 int 的地址吗,...)?