[英]C++ alignment when printing cout <<
使用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 操作器。 然而,也就是說,那些 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 庫,請運行(不要走)並改用Boost.Format庫。 它與標准 iostreams 完全兼容,它為您提供了使用 printf/Posix 格式化字符串輕松格式化的所有優點,但不會失去 iostreams 本身的任何功能和便利性。 例如,前兩行的第一部分看起來像:
// using Boost.Format
cout << format("%-20s %-20s %-8s\n") % "Artist" % "Title" % "Price";
cout << format("%-20s %-20s %8.2f\n") % "Merle" % "Blue" % 12.99;
另請參閱: 應在 C++ 代碼中使用哪個 CI/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;
}
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 個字符等。
IO 操縱器正是您所需要的。 setw ,特別是。 這是參考頁面中的示例:
// setw example
#include <iostream>
#include <iomanip>
using namespace std;
int main () {
cout << setw (10);
cout << 77 << endl;
return 0;
}
護短領域的左側和右側與done left
和right
機械手。
也看看setfill 。 這是關於使用 io manipulators 格式化 C++ 輸出的更完整教程。
在你發出第一行的時候,
Artist Title Price Genre Disc Sale Tax Cash
要實現“對齊”,您必須“提前”知道每列需要多寬(否則,對齊是不可能的)。 一旦你知道每一列的寬度需要的(有幾種可能的方式來實現,取決於您的數據的來自),然后是setw
功能在其他答復中提到會有所幫助,或者(更殘酷;-)你可能會釋放出仔細計算的額外空格數(當然是笨重的)等。無論如何,我不建議使用制表符,因為通常您無法真正控制最終輸出設備將如何呈現這些。
回到核心問題,例如,如果您在某種vector<T>
中擁有每一列的值,例如,您可以執行第一次格式化傳遞以確定列的最大寬度(請務必考慮當然,列標題的寬度也是如此)。
如果您的行“一一”出現,並且對齊至關重要,則您必須在行進入時對其進行緩存或緩沖(如果它們適合,則在內存中,否則在稍后將“倒帶”的磁盤文件中並從頭開始重新閱讀),注意在行出現時保持更新“每列的最大寬度”的向量。 你不能輸出任何東西(甚至不是標題!),如果保持對齊是至關重要的,直到你看到最后一行(除非你以某種方式神奇地知道列的寬度,當然;-)。
C++20 std::format
選項<
、 ^
和>
根據https://en.cppreference.com/w/cpp/utility/format/formatter#Standard_format_specification ,以下內容應成立:
// left: "42 "
std::cout << std::format("{:<6}", 42);
// right: " 42"
std::cout << std::format("{:>6}", 42);
// center: " 42 "
std::cout << std::format("{:^6}", 42);
更多信息請訪問: std::string 格式,如 sprintf
不使用“復雜”函數的最簡單方法是手動格式化:
一個例子:
std::cout << std::setprecision(10)
<< "integral of sin(x) from x = 0 to x = pi" << '\n'
<< "approximate: " << integrate(a, b, nbins) << '\n'
<< "exact: " << 2.0 << '\n';
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.