【发布时间】:2014-08-21 10:09:05
【问题描述】:
测试
为了找出getline()遇到EOF时的行为,我写了如下测试:
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-D回车
结果:
length 4: abc //notice that '\n' is also taken into consideration and printed
输入2:
abc输入
完全相同的输出:
length 4: abc
EOF 似乎被getline() 忽略了
源代码
所以我找到了source code of getline(),以下是它的相关sn-p(为了简洁起见,我省略了一些cmets和不相关的代码):
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;
问题
所以我的问题是:
- 为什么这里的长度是 4(据我所知应该是 5)(正如wiki 所说,如果它不在行首,就不会是 EOF)
类似的问题:EOF behavior when accompanied by other values 但请注意该问题中的 getline() 与 GNU-getline 不同
我使用 GCC:(Ubuntu 4.8.2-19ubuntu1) 4.8.2
【问题讨论】:
-
作为测试,使用您的程序的二进制文件作为自己的输入:
./a.out <a.out它会报告一个很大的数字(当我尝试时:1317)。下一步:十六进制转储您的程序hexdump a.out | less并查找第一个04字符(在我的情况下它位于位置0x18)。结论:EOD (0x04) 字符不特殊。说明: EOD 只是由终端驱动程序处理不同。 -
在这里查看我的答案:stackoverflow.com/a/10766343/905902 演示终端如何处理“特殊”字符(它是关于 ^C,而不是 ^D,但机制相似)
-
len是 4,因为 (a+b+c+\n=4)。无需使用ctrl+d。只需a b c [enter]。 -
@wildplasser 抱歉这么晚了。谢谢。您能否详细解释一下您是如何得出结论的,因为我没有得到它。
-
大部分内容都被@mafso 覆盖。我的重点是:没有 EOF 字符。 (有时)有一个 EOF condition ,它 sometimes 被翻译成一个具有 EOF 值的 int。 mafso 的反应涵盖了这种反应被延迟的情况(由终端/终端驱动程序/原始输入和程序之间的缓冲)