繁体   English   中英

GNU-getline:关于EOF的奇怪行为

[英]GNU-getline: strange behaviour about 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);
}

而input1是:

a b c Ctrl-D 输入

结果:

 length 4: abc  //notice that '\n' is also taken into consideration and printed

输入2:

a b c 输入

完全相同的输出:

 length 4: abc

似乎EOFgetline()遗漏了

源代码

所以我找到了getline()源代码,以下是它的一个相关片段(我省略了一些注释和不相关的代码以简洁):

 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)(正如维基说的那样,如果它不在一行的开头就不会是EOF)

一个类似的问题: 伴随其他值时的EOF行为,在该问题中注意getline()与GNU-getline不同

我使用GCC:(Ubuntu 4.8.2-19ubuntu1)4.8.2

Ctrl-D会导致终端刷新输入缓冲区(如果尚未刷新)。 否则,设置输入流的文件结束指示符。 换行符也会刷新缓冲区。

所以你没有关闭流,但只刷新输入缓冲区,这就是getline没有看到文件结束指示符的原因。

在这两种情况下, getline都接收到文字EOT 字符 (ASCII 0x04, ^D )(为此,您可以键入Ctrl-V Ctrl-D )。

类型

a b c Ctrl-D Ctrl-D

要么

a b c 输入 Ctrl-D

实际设置文件结束指标。

来自POSIX

特殊的角色

  • EOF

输入上的特殊字符,如果设置了ICANON标志,则会识别该ICANON 收到后,等待读取的所有字节将立即传递给进程,而不等待<newline> ,并丢弃EOF。 因此,如果没有字节等待(即,EOF发生在一行的开头),则应从read()返回字节计数为零,表示文件结束指示。 如果ICANON ,则处理时应丢弃EOF字符。

仅供参考, 此处指定ICANON标志。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM