Partager via


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.

Alignment

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 setwresetiosflags , 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::scientificen , 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, octet 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.

Voir aussi

Flux de sortie