C GNU getline:关于EOF的奇怪行为 试验
为了找到遇到EOF时C GNU getline:关于EOF的奇怪行为 试验,c,linux,eof,C,Linux,Eof,为了找到遇到EOF时getline()的行为,我编写了以下测试: int main (int argc, char *argv[]) { size_t max = 100; char *buf = malloc(sizeof(char) * 100); size_t len = getline(&buf, &max, stdin); printf("length %zu: %s", len, buf); } 输入1是: abcCtrl登特 结果:
getline()
的行为,我编写了以下测试:
int main (int argc, char *argv[]) {
size_t max = 100;
char *buf = malloc(sizeof(char) * 100);
size_t len = getline(&buf, &max, stdin);
printf("length %zu: %s", len, buf);
}
输入1是:
abcCtrl登特
结果:
length 4: abc //notice that '\n' is also taken into consideration and printed
输入2:
abcEnter
完全相同的输出:
length 4: abc
似乎EOF
被getline()
源代码
因此,我发现,以下是其中的一个相关片段(为了简洁起见,我省略了一些注释和不相关的代码):
问题:
所以我的问题是:
- 为什么这里的长度是4(据我所知应该是5)(如前所述,如果不是在一行的开头,它就不会是EOF)
getline
没有看到文件结束指示器的原因
在这两种情况下,getline
都会接收文字字符(ASCII 0x04,^D
)(为此,可以键入Ctrl-VCtrl-D)
类型
abcCtrl-DCtrl-D
或
abcEnterCtrl-D
以实际设置文件结束指示器
发件人:
特殊字符
- EOF
ICANON
标志,则可识别该字符。收到后,等待读取的所有字节将立即传递给进程,而无需等待
,EOF将被丢弃。因此,如果没有等待的字节(即,EOF发生在行的开头),则从read()
返回的字节计数应为零,表示文件结束指示。如果设置了ICANON
,则处理时应丢弃EOF字符
仅供参考,指定了ICANON标志。任何关于“Ctrl-D导致终端刷新输入缓冲区”的引用?此外,维基百科说,“驱动程序将一行开头的Control-D字符转换为文件结尾的指示符。”这是错误的吗?似乎是正确的。如果运行
cat
,在不按enter键的情况下键入一些文本,然后按^D,cat
将立即回显您目前键入的内容。不幸的是,没有。我找到了,尽管没有引用。你从维基百科上引用的话没有错(也没有反驳我),只是不完整。它没有说明如果未在行首按^D
会发生什么情况。注意:如果使用转义约定的实用程序在转义后立即检测到文件结束条件,则结果未指定。没什么帮助,但似乎是POSIX指定了^D
。但是我找不到它。这些问题经常出现在这里,我发现的所有副本也都没有引用来源(而且大多数根本没有提到当不是在行首按下^D
时会发生什么)。如果我们能找到它的来源/具体位置,那就太好了。我想我们同意。查看my/a.out作为测试,使用程序的二进制文件作为自己的输入:/a.out在这里查看我的答案:有关终端如何处理“特殊”字符的演示(它是关于^C,而不是^D,但机制类似)len
是4,因为(a
+b
+C
+++\n
=4
). 无需使用ctrl+d
。只需abc[enter]
@wildplasser很抱歉这么晚了。谢谢你能详细解释一下你是如何得出这个结论的吗?因为我没有弄明白。大部分结论都在@mafso中。我的重点是:没有EOF字符。这里(有时)有一个EOF条件,它有时被转换成一个值为EOF的int。mafso的反应涵盖了这种反应延迟的情况(通过终端/终端驱动程序/原始输入和程序之间的缓冲)
while ((c = getc (stream)) != EOF)
{
/* Push the result in the line. */
(*lineptr)[indx++] = c;
/* Bail out. */
if (c == delim) //delim here is '\n'
break;
}
/* Make room for the null character. */
if (indx >= *n)
{
*lineptr = realloc (*lineptr, *n + line_size);
if (*lineptr == NULL)
return -1;
*n += line_size;
}
/* Null terminate the buffer. */
(*lineptr)[indx++] = 0;
return (c == EOF && (indx - 1) == 0) ? -1 : indx - 1;