use*_*818 5 c++ cout setw multiple-columns
所以我刚刚开始学习 C++,我很好奇它是否是一种用 cout 格式化输出的方法,这样它看起来会很漂亮并且按列结构化
例如。
string fname = "testname";
string lname = "123";
double height = 1.6;
string fname2 = "short";
string lname2 = "123";
double height2 = 1.8;
cout << "Name" << setw(30) << "Height[m]" << endl;
cout << fname + " " + lname << right << setw(20) << setprecision(2) << fixed << height << endl;
cout << fname2 + " " + lname2 << right << setw(20) << setprecision(2) << fixed << height2 << endl
Run Code Online (Sandbox Code Playgroud)
输出如下所示:
Name Height[m]
testname 123 1.60
short 123 1.80
Run Code Online (Sandbox Code Playgroud)
我希望它看起来像这样:
Name Height[m]
testname 123 1.60
short 123 1.80
Run Code Online (Sandbox Code Playgroud)
我试图解决的问题是,我想将高度放置在名称的特定位置,但根据我取的名称长度,高度值要么远离右侧,要么非常靠近左侧。有没有办法来解决这个问题?
首先,对于像这样的输出流std::cout,您无法回到过去并修改已经执行的输出。这是有道理的——想象一下std::cout写入一个文件,因为您使用 启动了程序program.exe > test.txt,并且test.txt位于 USB 驱动器上,但同时已断开连接......
所以你必须立即把它做好。
基本上,有两种方法可以做到这一点。
您可以假设第一列中的任何条目都不会比一定数量的字符宽,这正是您所尝试的。问题是你的setw位置错误,而right应该是left。必须将流操纵器放置在应受影响的元素之前。由于您想要左对齐列,因此您需要left:
cout << left << setw(20) << "Name" << "Height[m]" << endl;
cout << left << setw(20) << fname + " " + lname << setprecision(2) << fixed << height << endl;
cout << left << setw(20) << fname2 + " " + lname2 << setprecision(2) << fixed << height2 << endl;
Run Code Online (Sandbox Code Playgroud)
但这个解决方案不是很通用。如果您的名字有 21 个字符怎么办?还是30个字符?还是100个字符?您真正想要的是一种解决方案,其中列仅根据需要自动设置宽度。
执行此操作的唯一方法是在打印之前收集所有条目,找到最长的条目,相应地设置列宽,然后才打印所有内容。
这是这个想法的一种可能的实现:
std::vector<std::string> const first_column_entries
{
"Name",
fname + " " + lname,
fname2 + " " + lname2
};
auto const width_of_longest_entry = std::max_element(std::begin(first_column_entries), std::end(first_column_entries),
[](std::string const& lhs, std::string const& rhs)
{
return lhs.size() < rhs.size();
}
)->size();
// some margin:
auto const column_width = width_of_longest_entry + 3;
std::cout << std::left << std::setw(column_width) << "Name" << "Height[m]" << "\n";
std::cout << std::left << std::setw(column_width) << fname + " " + lname << std::setprecision(2) << std::fixed << height << "\n";
std::cout << std::left << std::setw(column_width) << fname2 + " " + lname2 << std::setprecision(2) << std::fixed << height2 << "\n";
Run Code Online (Sandbox Code Playgroud)
进化的下一步将是将 概括std::vector为一个名为 的自编写类Table,并Table在循环中迭代该类的行以打印条目。