这个问题是关于POSIX C函数getline
。POSIX getline() - EOF上的行缓冲区状态?
该文档指出getline
在出错时(包括EOF)返回-1,但它没有说明在这些情况下变为lineptr
或n
。
我知道某些错误可能会以不同的方式处理 - 例如失败的realloc
- 但EOF如何? lineptr
和n
仍然保留其原始值?它是具体实现吗?未定义的行为?
这个问题是关于POSIX C函数getline
。POSIX getline() - EOF上的行缓冲区状态?
该文档指出getline
在出错时(包括EOF)返回-1,但它没有说明在这些情况下变为lineptr
或n
。
我知道某些错误可能会以不同的方式处理 - 例如失败的realloc
- 但EOF如何? lineptr
和n
仍然保留其原始值?它是具体实现吗?未定义的行为?
如果你看看这些POSIX文件http://pubs.opengroup.org/onlinepubs/9699919799/functions/getdelim.html 你会看到该函数不返回-1,如果它读取数据流中的最后一行和EOF不换行发生(即最后一行没有换行符)。所以当你到达EOF时,缓冲区的内容并不重要,因为getline不会写入任何内容。
“所以当你到达EOF”可能更清楚地理解为“因此,当函数返回-1因为EOF”,因为即使读取和写入字节到缓冲区EOF可以达到。 –
@ChronoKitsune是的,这可能更好,虽然POSIX文档说得很清楚。我可能不应该试图解释文档。 – Stuart
lineptr
和n
的值是特定于实现的。 getline()函数在读取EOF时可能会或可能不会重新分配缓冲区。
我以Illumos,NetBSD和FreeBSD为例。我看getdelim(),因为所有3个系统都有getline()调用带分隔符'\ n'的getdelim()。
__filbuf
来读取文件之前,总是尝试使用至少128字节的缓冲区。所以,如果你通过*lineptr = NULL
并且它读取EOF,你会回到*n = 128
和*lineptr
指向128字节的垃圾。__srefill
读取文件,然后再尝试进行任何重新分配。如果它读取EOF,则返回与您通过的相同的*lineptr
。如果您通过了*lineptr = NULL
,NetBSD确实设置了*n = 0
。*lineptr
为NULL,FreeBSD会分配一个1字节的缓冲区。这与NetBSD和Illumos不同,因为这些系统不会在缓冲区中放入空字符串。总之,当getline()读取EOF时,*lineptr
的值可能会也可能不会更改,并且它可能指向或不指向空字符串。
我同意当'getline'失败时缓冲区应该被释放,但是在失败时仍然没有提及缓冲区内容的状态。无论哪种方式,在'-1'返回定义好之后听起来不像访问缓冲区,所以最好不要依赖它。 –
@ Mr.Llama顺便说一句,我不明白你为什么想知道'EOF'。为什么你要保存数据到getline()'没有错误返回时已经解析过的缓冲区中?思考完后,这看起来像是一个XY问题。 – Stargateur
我有一个单行缓冲区,我想在EOF之前打印最后一行。问题是,如果'getline'为EOF返回-1,我不能保证我的行缓冲区对于打印仍然有效。现在我正在通过使用两行缓冲区来解决它。 –