9

我需要读取一个文件并将其中的文本发送到一个字符串,以便我可以解析它。但是,程序不会确切知道文件的长度,所以如果我想使用 ,我会怎么做fgets(),或者有更好的选择吗?

笔记:

char *fgets(char *str, size_t num, FILE *stream);
4

4 回答 4

10

不要忘记fgets()一次读取一行,前提是有足够的空间。

人类很少写长于... 80、256 的行,选择一个数字... 字符。POSIX 建议行长为 4096。所以,我通常使用:

char buffer[4096];

while (fgets(buffer, sizeof(buffer), fp)) 
{
    ...process line...
}

如果您担心有人可能在一行中提供超过 4K 的数据(并且机器生成的文件,例如 HTML 或 JSON,可能包含该数据),那么您必须决定下一步该做什么。您可以执行以下任何操作(可能还有一些我没有提到的其他选项):

  1. 以位为单位处理过长的行,而不假设中间有换行符。
  2. 为更长的行分配内存(例如 8K 开头),将初始 4K 复制到分配的缓冲区中,然后将更多数据读入缓冲区的后半部分,迭代直到找到行尾。
  3. getline()使用Linux 上可用的 POSIX 2008 功能。它为您分配内存。
于 2010-05-21T04:40:04.427 回答
3

如果您不在 POSIX 系统上并且没有getline可用的资源,请查看Chuck Falconer 的公共域ggets/fggets函数,它动态增长缓冲区以消耗整行。(该链接现在似乎已关闭,但archive.org 有一个副本。)

于 2010-05-21T05:16:55.213 回答
3

您可以迭代地使用 fgets,但更简单的替代方法是 (stdio.h's) getline。它在 POSIX 中,但不是标准的 C。

由于您使用的是 C++,您可以使用 std::string 函数,如 iostream 的getline吗?

于 2010-05-21T04:25:07.663 回答
0

分配一个缓冲区(str指向的那个),并将缓冲区的大小传递给num. 实际占用的空间只是 . 读取的文本的长度fgets

就像是:

char str[1000];
fgets(str, 1000, &file);

如果下一行在换行符之前只有 10 个字符,则 str 将保存这 10 个字符、换行符和空终止符。

编辑:以防万一有任何混淆,我并不想让上面的声音听起来好像缓冲区中的额外空间没有被使用。我只是想说明您不需要提前知道您的字符串将有多长,只要您可以在其上设置最大长度即可。

于 2010-05-21T04:24:47.030 回答