Mélanger cin et getline sous Linux et Windows

Je suis conscient du problème commun avec le mélange de cin et getline. Je crois que c’est différent

C’est le programme:

#include  #include  #include  using namespace std; int main() { int a; ssortingng line; cin >> a; printf("A is '%d'\n", a); getline(cin, line); printf("Line is '%s'\n", line.c_str()); cout << cin.fail() << cin.eof() << cin.bad() << endl; } 

J’ai aussi une version écrite en utilisant istream :: getline. Je crois que les résultats sont les mêmes dans tous les cas de saisie donnés ici.

 a.out < test1 A is '1' 'ine is ' abc 2 000 a.out < test2 A is '1' Line is ' abc 2' 000 

où test1 est $'1 abc 2\r\n' (9 octets) et test2 est $'1 abc 2\n' (8 octets).

Je n’ai pas explicitement fait ces tests sous Windows, mais j’ai l’impression que la sortie est “comme prévu”, c’est-à-dire identique à la sortie du test 2.

Ma question est la suivante: expliquez la sortie du test 1. Par exemple: pourquoi la sortie de printf est-elle corrompue? Existe-t-il un problème de portabilité lié à l’interprétation des fins de ligne? Comment le code peut-il être corrigé avec un minimum de changement de logique?

Sous Linux, getline supprime \n du stream d’entrée. Cependant, cela ne supprime pas le \r .

Le retour chariot ( \r ) renvoie le curseur au début de la ligne en cours. Ainsi, dans l’appel printf , le curseur STDOUT est renvoyé au début de la ligne lorsqu’il voit le \r . Le prochain caractère imprimé est le ' , qui écrase le premier caractère de la ligne (le L ).

Vous ne voyez pas ce comportement quand il n’y a pas de \r dans le fichier.

Solution facile pour résoudre ce problème: recherchez manuellement \r lors de l’exécution sous Linux et Unix.