Alignement C++ lors de l'impression cout

y a-t-il un moyen d'aligner le texte lors de l'impression en utilisant std::cout ? J'utilise des onglets, mais quand les mots sont trop gros, ils ne seront plus alignés.

Sales Report for September 15, 2010
Artist  Title   Price   Genre   Disc    Sale    Tax Cash
Merle   Blue    12.99   Country 4%  12.47   1.01    13.48
Richard Music   8.49    Classical   8%  7.81    0.66    8.47
Paula   Shut    8.49    Classical   8%  7.81    0.72    8.49
55
demandé sur q-l-p 2010-03-21 07:43:01

6 réponses

la méthode Standard ISO c++ est de #include <iomanip> et d'utiliser des manipulateurs comme std::setw . Cependant, cela dit, ces manipulateurs io sont une vraie douleur à utiliser, même pour le texte, et sont à peu près inutilisables pour le formatage des nombres (je suppose que vous voulez que vos montants de dollars s'alignent sur la décimale, avoir le nombre correct de chiffres significatifs, etc.). Même pour les étiquettes de texte simple, le code ressemblera à quelque chose comme ça pour la première partie de votre premier ligne:

// using standard iomanip facilities
cout << setw(20) << "Artist"
     << setw(20) << "Title"
     << setw(8) << "Price";
// ... not going to try to write the numeric formatting...

si vous êtes en mesure d'utiliser le Boost libraries , exécutez (ne marchez pas) et utilisez le Boost.Format bibliothèque à la place. Il est entièrement compatible avec la norme iostream, et il vous donne toute la bonté pour le formatage facile avec la chaîne de formatage printf/Posix, mais sans perdre aucune de la puissance et la commodité des iostream eux-mêmes. Par exemple, les premières parties de vos deux premières les lignes ressembleraient à quelque chose comme:

// using Boost.Format
cout << format("%-20s %-20s %-8s\n")  % "Artist" % "Title" % "Price";
cout << format("%-20s %-20s %8.2f\n") % "Merle" % "Blue" % 12.99;
115
répondu Herb Sutter 2013-08-28 09:31:59

Voir aussi: quelle bibliothèque C I/O doit être utilisée dans le code C++?

struct Item
{
   std::string     artist;
   std::string     c;
   integer         price;  // in cents (as floating point is not acurate)
   std::string     Genre;
   integer         disc;
   integer         sale;
   integer         tax;
};

std::cout << "Sales Report for September 15, 2010\n"
          << "Artist  Title   Price   Genre   Disc    Sale    Tax Cash\n";
FOREACH(Item loop,data)
{
    fprintf(stdout,"%8s%8s%8.2f%7s%1s%8.2f%8.2f\n",
          , loop.artist
          , loop.title
          , loop.price / 100.0
          , loop.Genre
          , loop.disc , "%"
          , loop.sale / 100.0
          , loop.tax / 100.0);

   // or

    std::cout << std::setw(8) << loop.artist
              << std::setw(8) << loop.title
              << std::setw(8) << fixed << setprecision(2) << loop.price / 100.0
              << std::setw(8) << loop.Genre
              << std::setw(7) << loop.disc << std::setw(1) << "%"
              << std::setw(8) << fixed << setprecision(2) << loop.sale / 100.0
              << std::setw(8) << fixed << setprecision(2) << loop.tax / 100.0
              << "\n";

    // or

    std::cout << boost::format("%8s%8s%8.2f%7s%1s%8.2f%8.2f\n")
              % loop.artist
              % loop.title
              % loop.price / 100.0
              % loop.Genre
              % loop.disc % "%"
              % loop.sale / 100.0
              % loop.tax / 100.0;
}
9
répondu Martin York 2017-05-23 11:47:20

manipulateurs IO sont ce dont vous avez besoin. setw , en particulier. Voici un exemple de la page de référence:

// setw example
#include <iostream>
#include <iomanip>
using namespace std;

int main () {
  cout << setw (10);
  cout << 77 << endl;
  return 0;
}

la justification du champ à gauche et à droite se fait avec les manipulateurs left et right .

regardez aussi setfill . Voici un tutoriel plus complet sur formater la sortie C++ avec des manipulateurs io .

8
répondu Eli Bendersky 2010-03-21 04:54:29

la fonction de manipulateur setw sera utile ici.

7
répondu codaddict 2010-03-21 04:44:58

une autre façon de rendre la colonne alignée est la suivante:

using namespace std;

cout.width(20); cout << left << "Artist";
cout.width(20); cout << left << "Title";
cout.width(10); cout << left << "Price";
...
cout.width(20); cout << left << artist;
cout.width(20); cout << left << title;
cout.width(10); cout << left << price;

nous devrions estimer la longueur maximale des valeurs pour chaque colonne. Dans ce cas, les valeurs de la colonne" artiste " ne doivent pas dépasser 20 caractères et ainsi de suite.

6
répondu Nguyen 2014-03-12 18:37:33

Au moment où vous émettez la première ligne,

Artist  Title   Price   Genre   Disc    Sale    Tax Cash

pour réaliser" l'alignement", vous devez savoir" à l'avance " quelle largeur chaque colonne devra avoir (sinon, l'alignement est impossible). Une fois que vous do connaître la largeur nécessaire pour chaque colonne (Il ya plusieurs façons possibles d'atteindre que selon l'origine de vos données), alors la fonction setw mentionnée dans l'autre réponse aidera, ou (plus brutalement;-) vous pourrait émettre le nombre soigneusement calculé d'espaces supplémentaires (clunky, pour être sûr), etc. Je ne recommande pas les onglets de toute façon, car vous n'avez aucun contrôle réel sur la façon dont le périphérique de sortie finale Les affichera, en général.

retour à la question principale, si vous avez la valeur de chaque colonne dans un vector<T> d'une certaine façon, par exemple, vous pouvez faire une première passe de formatage pour déterminer la largeur maximale de la colonne, par exemple (assurez-vous de tenir compte de la largeur de l'en-tête pour la colonne, aussi, bien sûr).

si vos lignes viennent" une par une", et que l'alignement est crucial, vous devrez mettre en cache ou tamponner les lignes au fur et à mesure qu'elles apparaissent (en mémoire si elles conviennent, sinon sur un fichier disque que vous pourrez plus tard" rembobiner "et relire dès le début), en prenant soin de garder à jour le vecteur de" largeurs maximales de chaque colonne " au fur et à mesure que les lignes apparaissent. Vous ne pouvez rien sortir (même pas les en-têtes!), si garder l'alignement est crucial, jusqu'à ce que vous avez vu la toute dernière rangée (à moins que vous d'une façon ou d'une autre magiquement avoir une connaissance préalable des largeurs des colonnes, bien sûr;-).

4
répondu Alex Martelli 2010-03-21 04:57:50