4

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

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

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

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

4

4 回答 4

2

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

于 2013-10-16T17:42:00.487 回答
1

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

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

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

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

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

于 2013-10-16T17:42:36.667 回答
1

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

%specifier 

说明符

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

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

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


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

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


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

于 2013-10-16T17:48:03.757 回答
0

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

于 2013-10-16T17:41:00.370 回答