簡體   English   中英

打印時C++ alignment <<

[英]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 leftright機械手。

也看看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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM