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

2024-03-22

Test

为了找到的行为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-DEnter

Result:

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

Input2:

abcEnter

完全相同的输出:

 length 4: abc

看来EOF被排除在外getline()

源代码

所以我找到了的源代码getline() http://sourcecodebrowser.com/pecomato/0.0.15/gnu-getline_8c.html以下是它的相关片段(为了简洁起见,我省略了一些注释和不相关的代码):

 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;

Question

所以我的问题是:

  • 为什么这里的长度是4(据我所知应该是5)(因为wiki http://en.wikipedia.org/wiki/End-of-file说,如果它不在行的开头,它就不会是 EOF)

类似的问题:伴随其他值时的 EOF 行为 https://stackoverflow.com/questions/17162167/eof-behavior-when-accompanied-by-other-values但请注意该问题中的 getline() 与 GNU-getline 不同

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


Ctrl-D causes your terminal to flush the input buffer if it isn’t already flushed. Otherwise, the end-of-file indicator for the input stream is set. A newline also flushes the buffer.

所以你没有关闭流,而只是刷新了输入缓冲区,这就是为什么getline没有看到文件结束指示器。

In neither of these cases, a literal EOT https://en.wikipedia.org/wiki/End-of-transmission_character character (ASCII 0x04, ^D) is received by getline (in order to do so, you can type Ctrl-VCtrl-D).

Type

abcCtrl-DCtrl-D

or

abcEnterCtrl-D

实际设置文件结束指示器。

From POSIX http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap11.html#tag_11:

特殊字符

  • EOF

输入时的特殊字符,如果ICANON标志已设置。当接收到时,所有等待读取的字节都会立即传递给进程,而无需等待<newline>,并且 EOF 被丢弃。因此,如果没有字节等待(即 EOF 发生在行的开头),则应从read(),表示文件结束指示。如果ICANON设置后,处理时 EOF 字符将被丢弃。

仅供参考,指定了 ICANON 标志here http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/termios.h.html.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐