Les entrés/sorties dans C++

de | 26 octobre 2018


Les exemples de programmes des sections précédentes ont fourni peu d’interaction avec l’utilisateur, voire pas du tout. Ils ont simplement imprimé des valeurs simples à l’écran, mais la bibliothèque standard offre de nombreuses autres manières d’interagir avec l’utilisateur via ses fonctions d’entrée / sortie. Cette section présentera une brève introduction à certains des plus utiles.

C ++ utilise une abstraction pratique appelée flux pour effectuer des opérations d’entrée et de sortie sur des supports séquentiels tels que l’écran, le clavier ou un fichier. Un flux est une entité dans laquelle un programme peut insérer ou extraire des caractères de / vers. Il n’est pas nécessaire de connaître les détails du support associé au flux ni de ses spécifications internes. Tout ce que nous avons besoin de savoir, c’est que les flux sont une source / destination de caractères et que ces caractères sont fournis / acceptés séquentiellement (c’est-à-dire l’un après l’autre).

La bibliothèque standard définit une poignée d’objets de flux pouvant être utilisés pour accéder à ce qui est considéré comme la source et la destination standard des caractères par l’environnement d’exécution du programme:

Flux                          Description
cin                             flux d’entrée standard
cout                          flux de sortie standard
cerr                           Erreur standard cerr (sortie)
clog                           flux de journalisation standard (en sortie)

Nous allons voir plus en détail uniquement cout et cin (les flux d’entrée et de sortie standard); cerr et clog sont également des flux de sortie, ils fonctionnent donc essentiellement comme des couts, la seule différence étant qu’ils identifient les flux à des fins spécifiques: messages d’erreur et journalisation; qui, dans de nombreux cas, dans la plupart des configurations d’environnement, ils font exactement la même chose: ils impriment à l’écran, bien qu’ils puissent également être redirigés individuellement.

Sortie standard (cout)

Sur la plupart des environnements de programme, la sortie standard par défaut est l’écran et l’objet de flux C ++ défini pour y accéder est cout.

Pour les opérations de sortie formatées, cout est utilisé avec l’opérateur d’insertion, qui est écrit sous la forme << (c’est-à-dire deux signes « inférieur à »).

cout << "Phrase de sortie"; // affiche la phrase de sortie à l'écran
cout << 120; // affiche le numéro 120 à l'écran
cout << x; // affiche la valeur de x à l'écran

L’opérateur << insère les données qui les suivent dans le flux qui les précède. Dans les exemples ci-dessus, il a inséré la chaîne littérale Phrase de sortie, le nombre 120 et la valeur de la variable x dans le flux de sortie standard cout. Notez que la phrase de la première instruction est placée entre guillemets (« ) car il s’agit d’un littéral de chaîne, alors que x ne l’est pas dans la dernière. La citation double est ce qui fait la différence; le texte est imprimé littéralement; s’il ne l’est pas, il est interprété comme l’identifiant d’une variable et sa valeur est imprimée. Par exemple, ces deux phrases ont des résultats très différents:

cout << "Bonjour"; // imprime bonjour
cout << Bonjour; // affiche le contenu de la variable Hello

Plusieurs opérations d’insertion (<<) peuvent être chaînées en une seule instruction:

cout << "Ce" << "est une" << "instruction unique C ++";

Cette dernière instruction imprimerait le texte. Il s’agit d’une seule instruction C ++. Le chaînage des insertions est particulièrement utile pour mélanger des littéraux et des variables dans une seule instruction:

cout << "J'ai" << age << "ans et mon code postal est" << codepostal;

En supposant que la variable age contienne la valeur 24 et que la variable zipcode contienne 90064, la sortie de l’instruction précédente serait:

J’ai 24 ans et mon code postal est 90064

Ce que cout ne fait pas automatiquement, c’est d’ajouter des sauts de ligne à la fin, sauf instruction contraire. Par exemple, prenons les deux instructions suivantes pour insérer dans cout:

cout << "Ceci est une phrase.";
cout << "Ceci est une autre phrase.";

La sortie serait dans une seule ligne, sans aucune rupture de ligne entre les deux. Quelque chose comme:

Ceci est une phrase. Ceci est une autre phrase.
Pour insérer un saut de ligne, un caractère de nouvelle ligne doit être inséré à la position exacte de la ligne. En C ++, un caractère de nouvelle ligne peut être spécifié sous la forme \ n (c’est-à-dire une barre oblique inversée suivie d’un n minuscule). Par exemple:

cout << "Première phrase. \ n";
cout << "Deuxième phrase. \ nTroisième phrase.";

Cela produit la sortie suivante:

Première phrase.
Deuxième phrase.
Troisième phrase.

Alternativement, le manipulateur endl peut également être utilisé pour rompre des lignes. Par exemple:

cout << "Première phrase." << endl;
cout << "Deuxième phrase." << endl;

Cela imprimerait:

Première phrase.
Deuxième phrase.

Le manipulateur endl produit un caractère de nouvelle ligne, exactement comme l’insertion de ‘\ n’; mais il a également un comportement supplémentaire: la mémoire tampon du flux (le cas échéant) est vidée, ce qui signifie que la sortie doit être écrite physiquement sur le périphérique, si ce n’est déjà fait. Cela concerne principalement les flux entièrement mis en mémoire tampon, et cout n’est (généralement) pas un flux entièrement mis en mémoire tampon. Néanmoins, c’est généralement une bonne idée d’utiliser endl uniquement lorsque vider le flux serait une fonctionnalité et ‘\ n’ s’il ne le ferait pas. N’oubliez pas qu’une opération de rinçage engendre des frais généraux particuliers et peut entraîner un retard sur certains appareils.

Entrée standard (cin)

Dans la plupart des environnements de programme, l’entrée standard par défaut est le clavier et l’objet de flux C ++ défini pour y accéder est cin.

Pour les opérations d’entrée formatées, cin est utilisé avec l’opérateur d’extraction, qui est écrit sous la forme >> (c’est-à-dire deux signes « plus grand que »). Cet opérateur est ensuite suivi de la variable où sont stockées les données extraites. Par exemple:

int age;
cin >> age;

La première instruction déclare une variable de type int appelée age et la seconde extrait de cin une valeur à stocker. Cette opération oblige le programme à attendre l’entrée de cin; généralement, cela signifie que le programme attendra que l’utilisateur entre une séquence avec le clavier. Dans ce cas, notez que les caractères introduits à l’aide du clavier ne sont transmis au programme que lorsque vous appuyez sur la touche ENTER (ou RETURN). Une fois que l’instruction avec l’opération d’extraction sur cin est atteinte, le programme attendra aussi longtemps que nécessaire jusqu’à ce qu’une entrée soit introduite.

L’extraction sur cin utilise le type de la variable après l’opérateur >> pour déterminer la façon dont elle interprète les caractères lus à partir de l’entrée. s’il s’agit d’un entier, le format attendu est une suite de chiffres, s’il s’agit d’une chaîne de caractères, etc.

// i / o exemple

#include <iostream>
using namespace std;

int main ()
{
int i;
cout << "Veuillez entrer une valeur entière:";
cin >> i;
cout << "La valeur que vous avez entrée est" << i;
cout << "et son double est" << i * 2 << ". \ n";
retourne 0;
}

Résultat de l’exécution

Veuillez entrer une valeur entière: 702
La valeur que vous avez entrée est 702 et son double est 1404.

Comme vous pouvez le constater, l’extraction à partir de cin semble simplifier et simplifier l’obtention de l’entrée à partir de l’entrée standard. Mais cette méthode a aussi un gros inconvénient. Que se passe-t-il dans l’exemple ci-dessus si l’utilisateur entre autre chose qui ne peut pas être interprété comme un entier? Eh bien, dans ce cas, l’opération d’extraction échoue. Et cela, par défaut, permet au programme de continuer sans définir de valeur pour la variable i, produisant des résultats indéterminés si la valeur de i est utilisée ultérieurement.

C’est un très mauvais comportement du programme. La plupart des programmes sont censés se comporter comme prévu, quel que soit le type d’utilisateur, en gérant les valeurs non valides de manière appropriée. Seuls les programmes très simples doivent s’appuyer sur les valeurs extraites directement de cin sans autre vérification.

Nous verrons un peu plus tard comment utiliser les chaînes de caractères pour mieux contrôler les entrées de l’utilisateur.

Les extractions sur cin peuvent également être chaînées pour demander plusieurs données dans une seule instruction:

cin >> a >> b;

Ceci est équivalent à:

cin >> a;
cin >> b;

Dans les deux cas, l’utilisateur doit introduire deux valeurs, une pour la variable a et une autre pour la variable b. Tout type d’espace est utilisé pour séparer deux opérations d’entrée consécutives; cela peut être un espace, une tabulation ou un caractère de nouvelle ligne.

cin et string

L’opérateur d’extraction peut être utilisé sur cin pour obtenir des chaînes de caractères de la même manière que pour les types de données fondamentaux:

string mystring;
cin >> mystring;

Cependant, l’extraction cin considère toujours les espaces (espaces, tabulations, nouvelle ligne …) comme terminant la valeur en cours d’extraction, et extraire une chaîne signifie donc toujours extraire un seul mot, pas une phrase ou une phrase entière.

Pour obtenir une ligne entière de cin, il existe une fonction, appelée getline, qui prend le flux (cin) en premier argument et la variable de chaîne en second. Par exemple:

// cin avec des cordes
#include <iostream>
#include <string>
using namespace std;

int main ()
{
string mystr;
cout << "Quel est votre nom?";
getline (cin, mystr);
cout << "Bonjour" << mystr << ". \ n";
cout << "Quelle est votre équipe préférée?";
getline (cin, mystr);
cout << "J'aime" << mystr << "aussi! \ n";
retourne 0;
}

Résultat de l’execution :

Quel est votre nom? Homer Simpson
Bonjour Homer Simpson.
Quelle est votre équipe préférée? Les isotopes
J'aime les isotopes aussi!

Notez que dans les deux appels à getline, nous avons utilisé le même identifiant de chaîne (mystr). Lors du deuxième appel, le programme remplace simplement le contenu précédent par le nouveau contenu.

Le comportement standard attendu par la plupart des utilisateurs d’un programme de console est que chaque fois que le programme interroge l’utilisateur, il introduit le champ, puis appuie sur la touche Entrée (ou Retour). En d’autres termes, on s’attend généralement à ce que les entrées des programmes de console se fassent sur des lignes, et ceci peut être obtenu en utilisant getline pour obtenir les entrées de l’utilisateur.

Par conséquent, sauf si vous avez une raison valable de ne pas le faire, vous devez toujours utiliser getline pour obtenir des entrées dans vos programmes de console au lieu de les extraire de cin.




Catégorie : C++

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *