【问题标题】:Scan whole line from file in C Programming在 C 编程中从文件中扫描整行
【发布时间】:2013-10-16 17:37:43
【问题描述】:

我正在编写一个程序来从一个文件中输入多行。 问题是我不知道行的长度,所以我不能使用 fgets 因为我需要给出缓冲区的大小并且不能使用 fscanf 因为它停在一个空格标记处 我看到了一个解决方案,他建议对作为输入的每个字符使用 malloc 和 realloc,但我认为有一种更简单的方法,然后我发现有人建议使用

fscanf(file,"%[^\n]",line);

有没有人有更好的解决方案,或者有人可以解释一下上面的工作原理吗?(我还没有测试过)

如果需要,我使用 GCC 编译器

【问题讨论】:

  • 我很好奇:为什么你不能使用fgets()?我没看懂你上面的解释。

标签: c eol


【解决方案1】:

您可以使用getline(3)。它代表你分配内存,当你读完行后你应该释放它。

【讨论】:

  • 感谢通过语法从来不知道这个函数
  • 我也从来不知道这件事。它让我想起了 strdup(),这是复制字符串的最佳方式。
  • 请注意返回的字符串包含行尾本身。
【解决方案2】:

然后我发现有人建议使用fscanf(file,"%[^\n]",line);

这实际上是fgets(line, sizeof line, file); 的不安全版本。不要那样做。

如果您不知道文件大小,您有两种选择。

  1. 在 C 库的某处定义了一个 LINE_MAX 宏(AFAIK 仅适用于 POSIX,但某些实现可能具有等价物)。行不超过该长度是一个合理的假设。

  2. 您可以采用“读取和重新分配”方式,但不必为每个字符都使用realloc()。这个问题的传统解决方案是指数级地扩展缓冲区大小,即。 e.分配的内存用完时总是加倍。

【讨论】:

  • 扩展到上面的#2,在上述几何扩展缓冲区上重复使用fgets,直到最后一个字符读取实际上是换行符。或 fgets 由于 EOF(或任何其他原因,就此而言)而失败。 +1
  • @WhozCraig 谢谢。是的,这是正确的。万岁 2985775737 个字符长的行! :P
  • 1.在这个假设中,未使用的空间不是浪费吗,通常它也可能不足(编辑错字)
  • 2.是的,现在坚持这一点。将继续检查此页面以获得更好的解决方案
  • @KarthikNayak 1. 不,不是浪费。只是不要首先考虑优化,好吗? 2.
【解决方案3】:

scanf 或 fscanf 的简单格式说明符遵循此原型

%specifier 

说明符

我们知道d 是整数的格式说明符,像这样

[characters]Scanset 括号中指定的任意数量的字符。 在某些库实现中,不是第一个字符的破折号 (-) 可能会产生不可移植的行为。

[^characters]Negated scanset 任意数量的字符都没有指定为括号之间的字符。


fscanf(file,"%[^\n]",line);  

读取任何字符,直到出现Negated scanset 中的任何字符,在这种情况下为newline character


正如其他人建议的那样,您可以使用getline()fgets() 并查看example

【讨论】:

    【解决方案4】:

    fscanf(file,"%[^\n]",line); 行意味着它将把除\n 之外的任何内容读入line。我认为这应该适用于 Linux 和 Windows。但可能不适用于使用\r 结束一行的 OS X 格式。

    【讨论】:

    • 我们在 2013 年。OS X 不再使用\r。此外,这样做绝对是个坏主意,尤其是因为我们不知道线的大小。很容易出现缓冲区溢出错误。
    猜你喜欢
    • 2017-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多