【发布时间】:2017-05-14 21:54:04
【问题描述】:
这个问题是关于 POSIX C 函数getline。
文档指出 getline 在错误(包括 EOF)时返回 -1,但没有说明在这些情况下 lineptr 或 n 会变成什么。
我知道某些错误的处理方式可能不同 - 例如失败的realloc - 但是EOF呢? lineptr 和 n 是否仍保留其原始值?它是特定于实现的吗?未定义的行为?
【问题讨论】:
这个问题是关于 POSIX C 函数getline。
文档指出 getline 在错误(包括 EOF)时返回 -1,但没有说明在这些情况下 lineptr 或 n 会变成什么。
我知道某些错误的处理方式可能不同 - 例如失败的realloc - 但是EOF呢? lineptr 和 n 是否仍保留其原始值?它是特定于实现的吗?未定义的行为?
【问题讨论】:
【讨论】:
getline 失败时应该释放缓冲区,但这仍然没有说明失败时缓冲区内容的状态。无论哪种方式,在-1 return 定义明确之后,这听起来不像访问缓冲区,所以我最好不要依赖它。
EOF。为什么getline()无错误返回时,要保留已经解析过的缓冲区中的数据?想了想,这看起来像是一个 XY 问题。
getline 为EOF 返回-1,我不能保证我的行缓冲区对于打印仍然有效。现在我正在通过使用两个行缓冲区来解决它。
如果您查看这些 POSIX 文档 http://pubs.opengroup.org/onlinepubs/9699919799/functions/getdelim.html 如果函数读取流中的最后一行并且 EOF 发生时没有换行符(即最后一行没有换行符),您将看到该函数不会返回 -1。因此,当您到达 EOF 时,缓冲区的内容无关紧要,因为 getline 不会向其中写入任何内容。
【讨论】:
lineptr 和 n 的值是特定于实现的。 getline() 函数在读取 EOF 时可能会也可能不会重新分配缓冲区。
我以 Illumos、NetBSD 和 FreeBSD 为例。我看 getdelim() 因为所有 3 个系统都有 getline() 调用 getdelim() 和分隔符'\n'。
__filbuf 读取文件之前,总是会尝试至少 128 字节的缓冲区。因此,如果您传入 *lineptr = NULL 并读取 EOF,您将返回指向 128 字节垃圾的 *n = 128 和 *lineptr。__srefill 来读取文件,然后再尝试重新分配。如果它读取 EOF,您将返回您传入的 *lineptr。如果您传入 *lineptr = NULL,NetBSD 确实设置了 *n = 0。*lineptr 为NULL,FreeBSD 分配一个1 字节的缓冲区。这与 NetBSD 和 Illumos 不同,因为这些系统不会将空字符串放入缓冲区。总之,当 getline() 读取 EOF 时,*lineptr 的值可能会发生变化,也可能不会发生变化,它可能会或可能不会指向空字符串。
【讨论】: