簡體   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