使用 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 驱动器上,同时断开了连接...

所以你必须马上做对。

基本上,有两种方法。

您可以假设第一列中的任何条目都不会比一定数量的字符更宽[=4​​5=],这正是您所尝试的。问题是你的 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 的行为了打印条目。