Utilisation des opérateurs d’insertion et contrôle du format
Cette rubrique montre comment contrôler le format et comment créer des opérateurs d'insertion pour vos propres classes. L’opérateur d’insertion (<<
), qui préprogrammé pour tous les types de données C++ standard, envoie des octets à un objet de flux de sortie. Les opérateurs d’insertion fonctionnent avec des « manipulateurs » prédéfinis, qui sont des éléments qui modifient le format par défaut des arguments de type entier.
Vous pouvez contrôler le format avec les options suivantes :
Largeur de sortie
Pour aligner la sortie, vous spécifiez la largeur de sortie pour chaque élément en plaçant le setw
manipulateur dans le flux ou en appelant la width
fonction membre. Cet exemple aligne à droite les valeurs dans une colonne d'au moins 10 caractères de large :
// output_width.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;
int main( )
{
double values[] = { 1.23, 35.36, 653.7, 4358.24 };
for( int i = 0; i < 4; i++ )
{
cout.width(10);
cout << values[i] << '\n';
}
}
1.23
35.36
653.7
4358.24
Des espaces de début sont ajoutés à toute valeur dont la largeur est inférieure à 10 caractères.
Pour remplir un champ, utilisez la fill
fonction membre, qui définit la valeur du caractère de remplissage pour les champs dont la largeur est spécifiée. La valeur par défaut est un espace. Pour remplir la colonne de nombres avec astérisques, modifiez la boucle précédente for
comme suit :
for (int i = 0; i <4; i++)
{
cout.width(10);
cout.fill('*');
cout << values[i] << endl;
}
Le manipulateur endl
remplace le caractère de saut de ligne ('\n'
). Une sortie classique ressemble à ceci :
******1.23
*****35.36
*****653.7
***4358.24
Pour spécifier les largeurs des éléments de données sur la même ligne, utilisez le manipulateur setw
:
// setw.cpp
// compile with: /EHsc
#include <iostream>
#include <iomanip>
using namespace std;
int main( )
{
double values[] = { 1.23, 35.36, 653.7, 4358.24 };
const char *names[] = { "Zoot", "Jimmy", "Al", "Stan" };
for( int i = 0; i < 4; i++ )
cout << setw( 7 ) << names[i]
<< setw( 10 ) << values[i] << endl;
}
La width
fonction membre est déclarée dans <iostream>
. Si vous utilisez setw
ou n’importe quel autre manipulateur avec des arguments, vous devez inclure <iomanip>
. Dans la sortie, les chaînes s’impriment dans un champ de largeur 6 et des entiers dans un champ de largeur 10 :
Zoot 1.23
Jimmy 35.36
Al 653.7
Stan 4358.24
setw
et width
ne tronquent pas les valeurs. Si la sortie mise en forme dépasse la largeur, la valeur entière est imprimée, conformément au paramètre de précision du flux. Les deux setw
et width
affectent uniquement le champ suivant. La largeur de champ reprend son comportement par défaut (la largeur nécessaire) une fois qu'un champ a été imprimé. Toutefois, les autres options de format de flux restent en vigueur jusqu'à ce qu'elles soient modifiées.
Alignement
Les flux de sortie sont par défaut alignés à droite. Pour aligner à gauche les noms dans l’exemple précédent et aligner à droite les nombres, remplacez la for
boucle comme suit :
for (int i = 0; i <4; i++)
cout << setiosflags(ios::left)
<< setw(6) << names[i]
<< resetiosflags(ios::left)
<< setw(10) << values[i] << endl;
Une sortie classique ressemble à ceci :
Zoot 1.23
Jimmy 35.36
Al 653.7
Stan 4358.24
L’indicateur d’alignement gauche est défini à l’aide du setiosflags
manipulateur avec l’énumérateur left
. Cet énumérateur est défini dans la ios
classe. Sa référence doit donc inclure le ios::
préfixe. Le resetiosflags
manipulateur désactive l’indicateur d’alignement gauche. Contrairement width
à et setw
resetiosflags
, l’effet et setiosflags
est permanent.
Precision
La valeur par défaut pour la précision de virgule flottante est six. Par exemple, le nombre 3466,9768 est imprimé comme 3466,98. Pour modifier la façon dont cette valeur s’imprime, utilisez le setprecision
manipulateur. Le manipulateur a deux indicateurs : fixed
et scientific
. Si fixed
elle est définie, le nombre s’imprime sous la forme 3466.976800. Si scientific
elle est définie, elle s’affiche sous la forme 3.4669773+003.
Pour afficher les nombres à virgule flottante affichés dans Alignement avec un chiffre significatif, remplacez la for
boucle comme suit :
for (int i = 0; i <4; i++)
cout << setiosflags(ios::left)
<< setw(6)
<< names[i]
<< resetiosflags(ios::left)
<< setw(10)
<< setprecision(1)
<< values[i]
<< endl;
Le programme imprime cette liste :
Zoot 1
Jimmy 4e+01
Al 7e+02
Stan 4e+03
Pour éliminer la notation scientifique, insérez cette instruction avant la for
boucle :
cout << setiosflags(ios::fixed);
Avec la notation fixe, le programme imprime un chiffre après la virgule décimale.
Zoot 1.2
Jimmy 35.4
Al 653.7
Stan 4358.2
Si vous modifiez l’indicateur ios::fixed
ios::scientific
en , le programme imprime ceci :
Zoot 1.2e+00
Jimmy 3.5e+01
Al 6.5e+02
Stan 4.4e+03
Là encore, le programme imprime un chiffre après la virgule décimale. Si l’une ios::fixed
ou l’autre ios::scientific
est définie, la valeur de précision détermine le nombre de chiffres après la virgule décimale. Si ni l'un ni l'autre n'est défini, la valeur de précision détermine le nombre total de chiffres significatifs. Le manipulateur resetiosflags
efface ces indicateurs.
Base
Les dec
, oct
et hex
les manipulateurs définissent le radix par défaut pour l’entrée et la sortie. Par exemple, si vous insérez le hex
manipulateur dans le flux de sortie, l’objet traduit correctement la représentation interne des données des entiers dans un format de sortie hexadécimal. Les nombres sont affichés avec des chiffres à f en minuscules si l’indicateur uppercase
est clair (valeur par défaut) ; sinon, ils sont affichés en majuscules. Le radix par défaut est dec
(décimal).
Chaînes entre guillemets (C++14)
Lorsque vous insérez une chaîne dans un flux, vous pouvez facilement récupérer la même chaîne en appelant la stringstream::str()
fonction membre. Toutefois, si vous souhaitez utiliser l’opérateur d’extraction pour insérer le flux dans une nouvelle chaîne ultérieurement, vous pouvez obtenir un résultat inattendu, car l’opérateur >>
s’arrête par défaut lorsqu’il trouve le premier caractère d’espace blanc.
std::stringstream ss;
std::string inserted = "This is a sentence.";
std::string extracted;
ss << inserted;
ss >> extracted;
std::cout << inserted; // This is a sentence.
std::cout << extracted; // This
Ce problème peut être contourné manuellement, mais pour rendre l'aller-retour de chaîne plus pratique, C++14 ajoute le manipulateur de flux std::quoted
dans <iomanip>
. Lors de l’insertion, quoted()
entoure la chaîne d’un délimiteur (guillemets doubles ' " par défaut) et, lors de l’extraction, manipule le flux pour extraire tous les caractères jusqu’à ce que le délimiteur final soit trouvé. Les guillemets incorporés sont placés dans une séquence d’échappement avec un caractère d’échappement ('\\' par défaut).
Les délimiteurs sont présents uniquement dans l’objet de flux ; ils ne sont pas présents dans la chaîne extraite, mais ils sont présents dans la chaîne retournée par basic_stringstream::str
.
Le comportement d'espace blanc des opérations d'insertion et d'extraction est indépendant de la façon dont la chaîne est représentée dans le code. L'opérateur quoted est donc utile que la chaîne d'entrée soit un littéral de chaîne brut ou une chaîne standard. La chaîne d’entrée, quel que soit son format, peut avoir des guillemets incorporés, des sauts de ligne, des onglets, etc., et tous ces éléments seront conservés par le quoted()
manipulateur.
Pour plus d’informations et des exemples de code complets, consultez quoted
.