std::cout
を使用して印刷するときにテキストを揃える方法はありますか?私はタブを使用していますが、単語が大きすぎる場合、それらはもう整列されません。
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
ISO C++標準の方法は、#include <iomanip>
および std::setw
。ただし、これらのioマニピュレータはテキストでも使用するのは本当に苦痛であり、数字の書式設定にはほとんど使用できません(あなたはあなたのドル額を小数に揃えたい、有効桁数が正しいなどを仮定しています) 。)。プレーンテキストラベルの場合でも、最初の行の最初の部分のコードは次のようになります。
// using standard iomanip facilities
cout << setw(20) << "Artist"
<< setw(20) << "Title"
<< setw(8) << "Price";
// ... not going to try to write the numeric formatting...
ブーストライブラリ を使用できる場合は、(歩かないで)実行してBoost.Format代わりにライブラリ。標準のiostreamと完全に互換性があり、printf/Posix書式設定文字列を使用して簡単に書式設定するためのすべての利点を提供しますが、iostream自体のパワーと利便性を失うことはありません。たとえば、最初の2行の最初の部分は次のようになります。
// using Boost.Format
cout << format("%-20s %-20s %-8s\n") % "Artist" % "Title" % "Price";
cout << format("%-20s %-20s %8.2f\n") % "Merle" % "Blue" % 12.99;
参照: C++コードで使用するC I/Oライブラリはどれですか?
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;
}
IOマニピュレーターが必要です。 setw 、特に。リファレンスページの例を次に示します。
// setw example
#include <iostream>
#include <iomanip>
using namespace std;
int main () {
cout << setw (10);
cout << 77 << endl;
return 0;
}
左右のフィールドの調整は、left
およびright
マニピュレーターを使用して行います。
setfill もご覧ください。 ioマニピュレータを使用したC++出力のフォーマット に関するより完全なチュートリアルを次に示します。
setw マニピュレータ関数はここで役立ちます。
列を整列させる別の方法は次のとおりです。
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;
各列の値の最大長を推定する必要があります。この場合、「アーティスト」列の値は20文字を超えないようにしてください。
一番最初の行を出すとき、
Artist Title Price Genre Disc Sale Tax Cash
「アラインメント」を実現するには、各列の幅を「事前に」知る必要があります(そうでない場合、アラインメントは不可能です)。 do各列に必要な幅がわかったら(データの送信元に応じてそれを実現する方法はいくつかあります)、他の答えで言及されているsetw
関数は助け、または(より残酷に;-)慎重に計算された数の余分なスペースを出力することができます(確かに不格好です)。 、 一般に。
コアの問題に戻ります。各列の値がvector<T>
たとえば、最初の書式設定パスを実行して、たとえば列の最大幅を決定できます(もちろん、列のヘッダーの幅も考慮に入れてください)。
行が「1つずつ」来て、位置合わせが重要な場合は、入ってくる行をキャッシュまたはバッファリングする必要があります(収まる場合はメモリ内、そうでない場合は後で「巻き戻す」ディスクファイル上)行が来るたびに「各列の最大幅」のベクトルを更新し続けるように注意してください。整列を維持することが重要である場合、最後の行が表示されるまで何も出力できません(ヘッダーさえも!)(もちろん、列幅の魔法の前知識がない限り;-)。