POSIX getline() - EOF上的行缓冲状态?

时间:2016-12-30 15:47:44

标签: c posix getline

这个问题与POSIX C函数getline有关。

文档指出getline在出错时返回-1(包括EOF),但在这些情况下它没有说明lineptrn的内容。
我知道有些错误可能会有所不同 - 例如失败的realloc - 但是EOF呢? lineptrn仍保留其原始值吗?具体是实施吗?未定义的行为?

3 个答案:

答案 0 :(得分:5)

如果getline返回错误(EOF是此函数中的错误)。不应使用缓冲区中的数据。

如果函数读取至少1个字节,则不能返回

circuits,请注意该函数在某些情况下可以返回0.

此外,manual清楚地说:

  

即使getline()失败,用户程序也应释放此缓冲区。

  

在任何一种情况下,在成功通话时,* lineptr和* n都会更新   分别反映缓冲区地址和分配的大小。

这句话可以解释为缓冲区仅在成功通话时更新。

在我看来,程序应记录此错误并继续处理已读取的数据。注意:使用feof()来了解流是否已到达目的地。

答案 1 :(得分:3)

如果您查看这些POSIX文档http://pubs.opengroup.org/onlinepubs/9699919799/functions/getdelim.html 如果它读取流中的最后一行并且EOF在没有换行符的情况下发生(即最后一行没有换行符),您将看到该函数不返回-1。所以当你到达EOF时,缓冲区的内容无关紧要,因为getline不会写入任何内容。

答案 2 :(得分:1)

lineptrn的值是特定于实现的。 getline()函数在读取EOF时可能会或可能不会重新分配缓冲区。

我以Illumos,NetBSD和FreeBSD为例。我看看getdelim(),因为所有3个系统都有getline()调用带有分隔符'\ n'的getdelim()。

  • Illumos getdelim()总是在调用__filbuf来读取文件之前尝试至少128字节的缓冲区。因此,如果您传入*lineptr = NULL并且它读取了EOF,则会返回*n = 128并且*lineptr指向128字节的垃圾。
  • 在尝试任何重新分配之前,
  • NetBSD getdelim()始终调用__srefill来读取文件。如果它读取EOF,则会返回您传入的*lineptr。如果您传入*lineptr = NULL,则NetBSD会设置*n = 0
  • FreeBSD getdelim()在重新分配之前也会读取,但如果它读取EOF,则它会在缓冲区中放置一个'\ 0'(对于空字符串)。如果*lineptr为NULL,则FreeBSD分配一个1字节的缓冲区。这与NetBSD和Illumos不同,因为这些系统不会在缓冲区中放入空字符串。

总之,当getline()读取EOF时,*lineptr的值可能会也可能不会更改,并且它可能会也可能不会指向空字符串。