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)
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)
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)
向左和向右对齐场是使用left
和right
操纵器完成的.
另外看看setfill.这是一个关于使用io操纵器格式化C++输出的更完整的教程.
使列对齐的另一种方法如下:
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个字符,依此类推.
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::format
到fmt::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