打印cout <<时的C++对齐方式

use*_*514 60 c++ cout stdout text-alignment

使用打印时有没有办法对齐文字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
Run Code Online (Sandbox Code Playgroud)

Her*_*ter 122

ISO C++标准的方法是#include <iomanip>使用像io这样的操纵器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...
Run Code Online (Sandbox Code Playgroud)

如果您能够使用Boost库,请运行(不要走路)并使用Boost.Format库.它与标准的iostream完全兼容,它为您提供了使用printf/Posix格式化字符串轻松格式化的所有优点,但不会失去iostream本身的任何功能和便利.例如,前两行的第一部分看起来像:

// using Boost.Format
cout << format("%-20s %-20s %-8s\n")  % "Artist" % "Title" % "Price";
cout << format("%-20s %-20s %8.2f\n") % "Merle" % "Blue" % 12.99;
Run Code Online (Sandbox Code Playgroud)

  • 位置格式也很好,因为这意味着你可以从本地化文件中提取它们. (5认同)
  • `Boost.Format`看起来很棒.具有类型安全性的简单`printf`样式格式. (3认同)

Mar*_*ork 11

另请参见:在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;
}
Run Code Online (Sandbox Code Playgroud)


cod*_*ict 9

运输及工务局局长机械手功能将帮助这里.

  • 你还应该提到允许指定对齐的`left`和`right`以及允许指定完成哪个字符(默认为空格)的`setfill`. (3认同)

Eli*_*sky 9

IO操纵器是您所需要的.运输及工务局局长,尤其如此.以下是参考页面的示例:

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

int main () {
  cout << setw (10);
  cout << 77 << endl;
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

向左和向右对齐场是使用leftright操纵器完成的.

另外看看setfill.这是一个关于使用io操纵器格式化C++输出的更完整的教程.


Ngu*_*yen 7

使列对齐的另一种方法如下:

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;
Run Code Online (Sandbox Code Playgroud)

我们应该估计每列的最大值.在这种情况下,"Artist"列的值不应超过20个字符,依此类推.


Cir*_*四事件 5

C++20std::format选项<^以及>

根据https://en.cppreference.com/w/cpp/utility/format/formatter#Standard_format_specation应保持以下内容:

#include <format>

// left: "42    "
std::cout << std::format("{:<6}", 42);

// right: "    42"
std::cout << std::format("{:>6}", 42);

// center: "  42  "

std::cout << std::format("{:^6}", 42);
Run Code Online (Sandbox Code Playgroud)

现有的fmt库在获得官方支持之前就实现了它:https://github.com/fmtlib/fmt在 Ubuntu 22.04 上安装:

sudo apt install libfmt-dev
Run Code Online (Sandbox Code Playgroud)

修改源码替换:

  • <format><fmt/core.h>
  • std::formatfmt::format

主程序

#include <iostream>

#include <fmt/core.h>

int main() {
    std::cout << "123456.\n";
    // left
    std::cout << fmt::format("{:<6}.\n", 42);
    // right
    std::cout << fmt::format("{:>6}.\n", 42);
    // center
    std::cout << fmt::format("{:^6}.\n", 42);
}
Run Code Online (Sandbox Code Playgroud)

并编译并运行:

g++ -std=c++11 -o main.out main.cpp -lfmt
./main.out
Run Code Online (Sandbox Code Playgroud)

输出:

123456.
42    .
    42.
  42  .
Run Code Online (Sandbox Code Playgroud)

更多信息请参见:std::string 格式如 sprintf