Cependant, les programmeurs C ++ notent que ce qui se produit toujours, c'est que cin.eof () ne retourne "vrai" qu'après que la dernière ligne a été lue deux fois.
Ce n'est pas ce qui se passe. Le eofbitne joue aucun rôle dans la conversion en booléen ( stream::operator bool(ou operator void*en ancien c ++)). Seuls les badbitet failbitsont impliqués.
Supposons que vous lisez un fichier contenant des nombres séparés par des espaces. Une boucle basée autour cin.eof()sera inévitablement soit fausse, soit remplie de iftests. Vous ne lisez pas avant l'EOF. Vous lisez des chiffres. Alors, faites en sorte que votre code exprime cette logique:
while (stream >> some_var) {
process_value(some_var);
}
Cela fonctionnera que la dernière ligne du fichier se termine par 0 42\nou juste 0 42(pas de nouvelle ligne à la fin de la dernière ligne du fichier). Si le fichier se termine par 0 42\n, la dernière bonne lecture récupérera la valeur 42 et lira ce marqueur de fin de ligne final. Notez que le marqueur EOF n'a pas encore été lu. La fonction process_valueest appelée avec 42. Le prochain appel à l'opérateur d'extraction de flux >> lit l'EOF, et puisque rien n'a été extrait, les deux eofbitet failbitseront définis.
Supposons en revanche que le fichier se termine par 0 42(pas de nouvelle ligne à la fin de la dernière ligne). La dernière bonne lecture récupérera la valeur 42 se terminant sur le marqueur EOF. Vraisemblablement, vous voulez traiter cela 42. C'est pourquoi le eofbitne joue pas de rôle dans l'opérateur de conversion booléen du flux d'entrée. Lors du prochain appel à l'opérateur d'extraction de flux >>, la machine sous-jacente voit rapidement que le eofbitest déjà défini. Cela se traduit rapidement par la définition de la failbit.
Pourquoi le premier morceau de code ne fonctionne-t-il pas toujours correctement?
Parce que vous ne devriez pas rechercher EOF comme condition de boucle. La condition de boucle doit exprimer ce que vous essayez de faire, c'est-à-dire (par exemple), extraire des nombres d'un flux.