GNU-getline: comportement étrange à propos de EOF

Tester

Afin de trouver le comportement de getline() face à EOF, j’ai écrit le test suivant:

 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); } 

Et input1 est:

a b c Ctrl-D Entrée

Résultat:

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

Input2:

a b c Enter

Exactement la même sortie:

  length 4: abc 

Il semble que EOF soit getline() par getline()

Code source

Je trouve donc le code source de getline() et de ce qui suit est un extrait connexe (et je laisse de côté certains commentaires et codes non pertinents pour la concision):

  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

Donc ma question est:

  • pourquoi la longueur ici est 4 (autant que je sache, elle devrait être 5) (comme le dit wiki , ce ne sera pas un EOF s’il ne se trouve pas au début d’une ligne)

Une question similaire: le comportement EOF lorsqu’il est accompagné d’autres valeurs mais notez que getline () dans cette question est différent de GNU-getline

J’utilise GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2

Ctrl-D oblige votre terminal à vider le tampon d’entrée s’il n’est pas déjà vidé. Sinon, l’indicateur de fin de fichier du stream d’entrée est défini. Une nouvelle ligne vide également le tampon.

Ainsi, vous n’avez pas fermé le stream, mais seulement vidé le tampon d’entrée. C’est pourquoi getline ne voit pas d’indicateur de fin de fichier.

Dans aucun de ces cas, un caractère EOT littéral (ASCII 0x04, ^D ) est reçu par getline (pour ce faire, vous pouvez taper Ctrl-V Ctrl-D ).

Type

a b c Ctrl-D Ctrl-D

ou

a b c Entrez Ctrl-D

pour définir l’indicateur de fin de fichier.

De POSIX :

Caractères spéciaux

  • EOF

Caractère spécial en entrée, qui est reconnu si le drapeau ICANON est ICANON . Une fois reçus, tous les octets en attente de lecture sont immédiatement passés au processus sans attendre une et l’EOF est ignoré. Ainsi, s’il n’y a pas d’octets en attente (c’est-à-dire que l’EOF s’est produit au début d’une ligne), un compte d’octets égal à zéro doit être renvoyé par read() , représentant une indication de fin de fichier. Si ICANON est défini, le caractère EOF doit être supprimé lors de son traitement.

Pour info, le drapeau ICANON est spécifié ici .