Comment le C++ dialogue avec la console
Le C++ fait les E/S console à travers des flux issus de l'en-tête <iostream>. Tu écris vers le monde avec cout (sortie de caractères) et tu lis l'utilisateur avec cin (entrée de caractères). Ils utilisent deux opérateurs que tu as déjà vus comme décalages de bits, réaffectés ici :
<<est l'opérateur d'insertion : il envoie des données danscout.>>est l'opérateur d'extraction : il tire des données hors decinvers une variable.
Une astuce pour mémoriser le sens : les flèches pointent dans la direction où circulent les données. Maintenant que tu sais stocker du texte dans des chaînes, faisons entrer et sortir ce texte de ton programme.
Afficher avec cout
cout envoie vers la sortie standard tout ce que tu insères. Tu peux enchaîner plusieurs << dans une seule instruction, en mêlant librement texte, nombres et variables.
Chaque << s'ajoute à la même ligne jusqu'à ce que tu insères un saut de ligne. Tu as deux façons de le faire : '\n' insère un caractère de saut de ligne, tandis que endl insère un saut de ligne et vide le tampon vers l'écran. Le flush a un coût réel, donc dans une boucle qui affiche des milliers de lignes, préfère '\n' : le flux se vide tout seul quand il le faut (et toujours à la fin du programme).
// Très bien pour un message ponctuel :
cout << "Done" << endl;
// Dans une boucle intensive, préfère ceci - aucun flush forcé à chaque itération :
for (int i = 0; i < 1000000; ++i)
cout << i << '\n';
Lire avec cin et >>
cin >> variable lit un jeton délimité par des espaces et le convertit dans le type de la variable. Il ignore les espaces ou sauts de ligne en tête, puis s'arrête au prochain espace.
Comme >> s'arrête à l'espace, il est parfait pour des nombres isolés et des mots uniques, mais inutile pour une phrase complète : cin >> word sur l'entrée hello world ne lit que hello et laisse world dans le tampon pour la lecture suivante.
Lire une ligne entière avec getline
Pour capturer une ligne entière — espaces compris — utilise getline(cin, line), qui lit tout jusqu'à la touche Entrée dans une std::string.
C'est le bon outil dès que la saisie peut contenir des espaces : noms, adresses, phrases. Il n'y a qu'un seul piège qui t'attend dès l'instant où tu mélanges getline avec >>.
Le piège du saut de ligne entre cin et getline
C'est le bug d'E/S le plus courant en C++. Quand tu fais cin >> n, l'extraction lit le nombre mais laisse le saut de ligne (la touche Entrée que tu as appuyée) dans le tampon d'entrée. Le getline suivant voit ce saut de ligne résiduel immédiatement, considère la ligne comme déjà terminée et te rend une chaîne vide — sans jamais s'arrêter pour attendre une saisie.
int age;
string city;
cin >> age; // tu tapes 30 et appuies sur Entrée ; '\n' reste dans le tampon
getline(cin, city); // lit le '\n' résiduel -> city vaut "" (vide !)
La solution est d'écarter ce saut de ligne résiduel avec cin.ignore après le >> et avant le getline :
cin.ignore(numeric_limits<streamsize>::max(), '\n') saute les caractères jusqu'à avoir avalé un saut de ligne (ou atteint la fin de l'entrée). C'est la version robuste : la plus courte cin.ignore() n'écarte qu'un seul caractère, ce qui casse si l'utilisateur a tapé des espaces supplémentaires après le nombre. Adopte la forme complète par habitude.
Quand la saisie échoue
Si l'utilisateur tape des lettres là où tu attendais un nombre, l'extraction échoue : cin passe dans un état d'erreur et la variable cible reste inchangée (mise à 0 depuis C++11). Pire, une fois cin en état d'échec, toute lecture ultérieure est elle aussi ignorée silencieusement, et tu peux te retrouver dans une boucle infinie.
La récupération comporte toujours deux étapes : cin.clear() réinitialise les drapeaux d'erreur pour que le flux redevienne utilisable, et cin.ignore(...) jette les caractères fautifs encore coincés dans le tampon. Saute le ignore et la saisie incorrecte reste en place, donc le >> suivant échoue de nouveau — la classique boucle infinie. Vérifier cin >> n directement dans la condition fonctionne parce que le flux se convertit en false quand il est en état d'échec.
Erreurs courantes à éviter
- Utiliser
cin >> spour une phrase. Il s'arrête au premier espace. Utilisegetlinepour tout ce qui contient des espaces. - Oublier
cin.ignoreentre>>etgetline. Le saut de ligne résiduel te donne une ligne vide. Vide d'abord le tampon. - Recourir à
endlpartout. Chacun force un flush. Mets'\n'par défaut et réserveendlaux cas où la sortie doit vraiment apparaître maintenant. - Ignorer un
cinen échec. Des lettres dans une lecture numérique cassentcin; fais toujoursclear()puisignore()avant de relire.
Suite : Les flux de chaînes
Les E/S console et la manipulation de chaînes se rejoignent dans les flux de chaînes. Un stringstream te donne les mêmes opérateurs << et >>, mais pointés sur une chaîne en mémoire au lieu de la console — parfait pour analyser une ligne en nombres, construire du texte formaté et convertir entre chaînes et autres types sans jamais toucher au clavier.
Questions fréquentes
Pourquoi getline saute-t-il la saisie juste après l'utilisation de cin en C++ ?
cin >> x lit le nombre mais laisse dans le tampon le saut de ligne que tu as tapé. Le getline suivant lit jusqu'à ce saut de ligne résiduel et renvoie immédiatement une chaîne vide. Nettoie-le d'abord avec cin.ignore(numeric_limits<streamsize>::max(), '\n'); après le >> et avant le getline.
Quelle est la différence entre endl et \n en C++ ?
Les deux terminent la ligne, mais endl vide (flush) en plus le tampon de sortie vers l'écran, tandis que '\n' insère seulement un saut de ligne. Le flush a un coût : dans une boucle serrée, préfère '\n' et laisse le flux se vider de lui-même. N'utilise endl que lorsque tu as réellement besoin que la sortie apparaisse tout de suite.
Comment lire une ligne entière de texte, espaces compris, en C++ ?
Utilise getline(cin, line), pas cin >> line. L'opérateur >> s'arrête au premier espace, il ne récupère donc qu'un seul mot. getline lit tout jusqu'à la touche Entrée dans une std::string, espaces inclus.