使用 cout 的 C++ 设置列
C++ setup columns using cout
所以我才刚刚开始学习 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
输出如下所示:
Name Height[m]
testname 123 1.60
short 123 1.80
我希望它看起来像这样:
Name Height[m]
testname 123 1.60
short 123 1.80
我要解决的问题是,我想将高度放在名称的特定位置,但取决于名称的长度,我采用的高度值要么远离右侧,要么非常接近靠左。有办法解决这个问题吗?
string fname = "testname";
string lname = "123";
double height = 1.6;
string fname2 = "short";
string lname2 = "123";
double height2 = 1.8;
cout << left << setw(30) << "Name" << left << "Height[m]" << endl;
cout << left << setw(30) << fname + " " + lname << right << setw(6) << setprecision(2) << fixed << height << endl;
cout << left << setw(30) << fname2 + " " + lname2 << right << setw(6) << setprecision(2) << fixed << height2 << endl;
首先,对于像 std::cout
这样的输出流,您 无法及时返回 并修改已经执行的输出。这是有道理的——想象一下 std::cout
写入了一个文件,因为你用 program.exe > test.txt
启动了你的程序,而 test.txt
在 USB 驱动器上,同时断开了连接...
所以你必须马上做对。
基本上,有两种方法。
您可以假设第一列中的任何条目都不会比一定数量的字符更宽[=45=],这正是您所尝试的。问题是你的 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;
但是这个方案不是很通用。如果你的名字有 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";
进化的下一步是将 std::vector
概括为一个名为 Table
的自写 class 并在循环中迭代 Table
的行为了打印条目。
所以我才刚刚开始学习 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
输出如下所示:
Name Height[m]
testname 123 1.60
short 123 1.80
我希望它看起来像这样:
Name Height[m]
testname 123 1.60
short 123 1.80
我要解决的问题是,我想将高度放在名称的特定位置,但取决于名称的长度,我采用的高度值要么远离右侧,要么非常接近靠左。有办法解决这个问题吗?
string fname = "testname";
string lname = "123";
double height = 1.6;
string fname2 = "short";
string lname2 = "123";
double height2 = 1.8;
cout << left << setw(30) << "Name" << left << "Height[m]" << endl;
cout << left << setw(30) << fname + " " + lname << right << setw(6) << setprecision(2) << fixed << height << endl;
cout << left << setw(30) << fname2 + " " + lname2 << right << setw(6) << setprecision(2) << fixed << height2 << endl;
首先,对于像 std::cout
这样的输出流,您 无法及时返回 并修改已经执行的输出。这是有道理的——想象一下 std::cout
写入了一个文件,因为你用 program.exe > test.txt
启动了你的程序,而 test.txt
在 USB 驱动器上,同时断开了连接...
所以你必须马上做对。
基本上,有两种方法。
您可以假设第一列中的任何条目都不会比一定数量的字符更宽[=45=],这正是您所尝试的。问题是你的 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;
但是这个方案不是很通用。如果你的名字有 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";
进化的下一步是将 std::vector
概括为一个名为 Table
的自写 class 并在循环中迭代 Table
的行为了打印条目。