[C++] Les manipulateurs de flux

Formation

À Paris

Prix sur demande

Appeler le centre

Avez-vous besoin d'un coach de formation?

Il vous aidera à comparer différents cours et à trouver la solution la plus abordable.

Description

  • Typologie

    Formation

  • Lieu

    Paris

Nous vous proposons des cours ouverts pour se former autrement, pour devenir acteur de votre vie. Nous vous aidons à prendre votre envol, mais ça ne s'arrête pas là. Notre volonté est de vous accompagner tout au long de votre vie, dans votre parcours professionnel.Grâce à cette formation vous pourrez acquérir les connaissances nécessaires qui vous permettrons d’ajouter des compétences à votre profil et obtenir de solides aptitude qui vous offriront de nombreuses opportunités professionnelles.

Les sites et dates disponibles

Lieu

Date de début

Paris ((75) Paris)
Voir plan
7 Cité Paradis, 75010

Date de début

Consulter

Questions / Réponses

Ajoutez votre question

Nos conseillers et autres utilisateurs pourront vous répondre

À qui souhaitez-vous addresser votre question?

Saisissez vos coordonnées pour recevoir une réponse

Nous ne publierons que votre nom et votre question

Les Avis

Les matières

  • C++

Le programme

Introduction du cours

Bonjour tout le monde !

La première chose que l'on apprend à faire en programmation c'est à utiliser la console pour afficher du texte à l'intérieur. Puis petit à petit, on apprend aussi à y lire des informations et à écrire dans des fichiers.

Lors de toutes ces opérations, on aimerait souvent ajouter un peu d'esthétisme afin de rendre l'affichage plus joli ou mieux structuré.

Dans ce tutoriel, je vais vous apprendre à utiliser les manipulateurs de flux qui permettent facilement d'améliorer la lisibilité de vos sorties en console ou permettent par exemple de modifier le format de vos sorties dans les fichiers.

Pour comprendre ce tutoriel, il vaut mieux avoir lu la première partie du cours de M@teo21 sur le C++.

Petit rappel sur les flux

En C++, il existe plusieurs manières pour un programme d'interagir avec les éléments extérieurs que sont, la console, les fichiers, les périphériques, etc. Un des moyens particulièrement puissant d'interaction est le flux ou flot. Il existe des flux dans 2 directions, du programme vers l'extérieur et évidemment dans le sens contraire, ce qui permet ainsi d'influencer le déroulement d'un programme.
La bibliothèque standard du C++ propose 3 types différents de flux ayant chacun 2 directions. Ces flux sont des instances de classes dont les noms sont présentés dans le tableau suivant :

Type de flux

Flux entrant

Flux sortant

Fichier à inclure

Entrée/Sortie standard (console)

std::istream 

std:stream 

iostream

Flux sur les fichiers

std::ifstream 

std:fstream 

fstream

Flux sur les chaînes de caractères

std::istringstream 

std:stringstream 

sstream

Le dernier type de flux n'est pas fait pour interagir avec le monde extérieur mais plutôt pour utiliser la puissance des flux pour gérer plus facilement les chaînes de caractères.

Il est possible de créer autant de flux que l'on désire sur les chaînes de caractères ou sur les fichiers, en créant un objet des classes ci-dessus. Par contre il n'existe qu'un nombre restreint de flux vers la console disponibles de base. Ils sont au nombre de 4 :

Type de flux

Nom

Description

Entrant

std::cin 

Flux standard d'entrée

Sortant

std::cout 

Flux standard de sortie

Sortant

std::cerr 

Flux standard pour les erreurs (non-bufferisé)

Sortant

std::clog 

Flux standard pour les erreurs (bufferisé)

Les 2 derniers flux sont utilisés pour afficher des messages d'erreurs. std::cerr ne possède pas de buffer, cela veut dire qu'il affiche directement le contenu qui lui est passé sans attendre un appel à std::flush.

En réalité, l'ordinateur n'écrit pas directement dans la console ou dans un fichier lorsqu'on met quelque chose dans le flux. Il stocke ce qu'on lui passe dans une mémoire tampon et n'écrit réelement que lors d'un appel à std::flush, à std::endl, si la mémoire tampon est pleine ou si on est arrivé à la fin du programme. std::cerr ne possède pas de mémoire tampon, il écrit donc directement dans la console.

Tout cela est bien joli, mais comment les utilise-t-on ? C'est ce que je vais vous montrer tout de suite en basant mes exemples sur les flux standards std::cin et std::cout, puisque une fois le flux créé, l'utilisation est la même dans tous les cas. Comme vous l'aurez remarqué, on utilise tout le temps l'espace de nom std. A partir d'ici, je ne mettrais plus les std:: devant les fonctions que j'utilise. Ceci afin d'alléger l'écriture du code.

Pour plus d'informations sur la manière d'utiliser les flux sur les fichiers, je vous invite à lire l'excellent tutoriel de Xav57 intitulé Lecture et écriture dans les fichiers en C++.

Les flux sortant

Si vous avez lu le tutoriel de M@teo21, vous savez certainement que l'on utilise principalement un flux via l'opérateur << qui permet d'envoyer différents types de données dans le flux.

#include <iostream> using namespace std; cout << "Salut"; int entier=2; cout << entier; char lettre='b'; cout << lettre; string phrase = "Bonjour"; cout << phrase; //...

On peut donc via l'opérateur <<, envoyer des variables de nimporte quel type de base ainsi que les strings à un flux. Un des défauts de cette manière d'utiliser le flux est que les données sont affichées à la suite, sans aucune possibilité d'influencer la position des caractères ou le format des nombres affichés. Pour le faire, il faut utiliser les manipulateurs de flux que je vous présente dans la suite.

Si vous désirez forcer l'affichage dans la console, vous pouvez faire appel à endl ou flush. Le premier ajoutant en plus un retour à la ligne.

#include <iostream> using namespace std; int main() { cout << "Bonjour !" << flush << "Comment allez-vous ?" << endl; cout << "Bien et vous ?" << endl; //... }

produit l'affichage suivant :

Bonjour !Comment allez-vous ? Bien et vous ?Les flux entrant

Les flux entrant sont tout aussi simples à utiliser, il suffit de faire appel à l'opérateur >> pour lire les données et les stocker dans une variable.

#include <iostream> using namespace std; cout << "Entrez un nombre: "; int nombre; cin >> nombre; //nombre prend la valeur entrée par l'utilisateur //...

C'est donc extrêmement simple. Il y a juste un petit problème, si l'on essaye de lire une phrase complète contenant des espaces. En utilisant l'opérateur >> sur un flux entrant, la lecture s'arrête au premier "blanc". Pour lire une phrase, il faut alors passer par la fonction getline().

#include <iostream> #include <string> using namespace std; cout << "Entrez une phrase: "; string phrase; getline(cin,phrase); //Copie toute la ligne de ce qui se trouve dans le flux dans la //chaîne phrase. //...

Il est possible que la chose lue par le flux ne soit pas compatible avec la variable dans laquelle vous désirez la stocker. Vous aurez alors droit à une erreur et le comportement du flux sera alors indéfini. Pour plus de détails, je vous invite à lire ce tutoriel de ooprog.
Il faut également faire attention si vous mélangez les utilisations de >> et getline(), le symbole de fin de fichier peut subsister dans le flux. Je vous invite à suivre ce lien pour y remédier.

Voilà, c'est tout pour ce petit rappel sur les flux. Il est temps d'entrer dans le vif du sujet. Dans le but de simplifier les exemples, je vais utiliser le flux de sortie standard std::cout, mais il est possible d'utiliser les manipulateurs sur n'importe quel autre flux (std::ofstream, std::ostringstream, std::cerr, ...) . C'est ce qui sera fait dans l'exercice final.

Les manipulateurs basiquesSyntaxe des manipulateurs

Un manipulateur de flux est une instruction permettant de modifier le comportement du flux dans certains cas, par exemple afficher ou non les nombres après la virgule ou réaliser un alignement en colonne. Il existe deux syntaxes équivalentes pour utiliser un manipulateur.

La première manière correspond à un appel d'une fonction :

nom_du_manipulateur(nom_du_flux);

La deuxième s'appuie sur la surcharge de l'opérateur << pour les flux :

nom_du_flux << nom_du_manipulateur;

Personellement je préfère la deuxième méthode, mais les deux sont tout à fait équivalentes. Bon c'est bien joli tout ça, mais je crois que vous attendez un exemple.

Mon premier manipulateur

Il arrive souvent que l'on ait à afficher des booléens dans la console pendant que l'on développe pour vérifier que tout s'est bien passé. Il serait plus agréable de pouvoir afficher true et false, plutôt que 1 et 0. Pour cela, il existe le manipulateur boolalpha. Essayons pour voir :

#include <iostream> using namespace std; int main() { cout << true << " et " << false << endl; //Affichage "normal" cout << boolalpha; //On applique le manipulateur cout << true << " et " << false << endl; //Affichage "modifié" return 0; }

On aurait aussi pu écrire boolalpha(cout); à la ligne 7. Le résultat aurait été le même.

Ce qui nous donne :

1 et 0 true et false

C'est simple non ? Et encore, celui là on aurait pu le faire nous-même à l'aide d'une macro. Vous n'avez pas encore vu la suite !

Et si j'en veux plus de cet affichage ?

Bonne question ! Il suffit d'utiliser le manipulateur opposé, noboolalpha qui est justement là pour ça.

Les manipulateurs sur les nombres entiers

Vous savez certainement qu'il existe différentes manières de représenter un même nombre. Tout dépend de la base choisie. Nous, les êtres humains, utilisons la base 10. L'ordinateur, lui, ne connait que la base 2. C'est pourquoi les informaticiens sont parfois amener à utiliser les bases 8 et 16, appelées respectivement octal et hexadécimal. Il pourrait donc être intéressant d'afficher un nombre dans une ou l'autre de ces bases.
Pour cela, il existe 3 manipulateurs :

Nom

Fonction

dec

Affiche les nombres en base 10.(Valeur par défaut)

oct

Affiche les nombres en base 8.

hex

Affiche les nombres en base 16.

Essayons donc pour voir :

#include <iostream> using namespace std; int main() { cout << 33 << endl; //Affichage "normal" en base 10 cout << oct << 33 << endl; //Affichage en base 8 cout << hex << 33 << endl; //Affichage en base 16 cout << dec << 33 << endl; //Retour à la base 10 return 0; }

Ce qui donne comme prévu :

33 41 21 33

Les manipulateurs suivants, qui ont un effet sur les nombres réels ont aussi un effet sur les nombres entiers, ce qui n'est pas le cas des changements de base.

Les manipulateurs sur les nombres à virgule

A nouveau, il existe plusieurs manières d'afficher un nombre à virgule. On peut le faire en affichant tous les chiffres ou en utilisant la notation scientifique. Pour faire de même en C++, il faut utiliser les manipulateurs scientific et fixed pour forcer la représentation scientifique ou pour forcer la notation fixée.

Par défaut, le flux ne se trouve dans aucun des 2 cas. Si vous souhaitez remettre le flux dans son état original, il faut utiliser la fonction unsetf(flag) de la manière suivante: cout.unsetf(ios_base::scientific) ou
cout.unsetf(ios_base::fixed), selon la modification que vous avez faites. Cette fonction n'est pas directement associée aux manipulateurs, mais c'est la seule manière de le faire.

Un petit exemple :

#include <iostream> using namespace std; int main() { double nombre = 31223.565465; cout << nombre << endl; //Affichage "normal" cout << fixed << nombre << endl; //Affichage de tous les chiffres cout << scientific << nombre << endl; //Affichage scientifique return 0; }

Ce qui produit le résultat suivant :

Appeler le centre

Avez-vous besoin d'un coach de formation?

Il vous aidera à comparer différents cours et à trouver la solution la plus abordable.

[C++] Les manipulateurs de flux

Prix sur demande