5

所以我刚刚开始学习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

我要解决的问题是,我想将高度放置在名称的特定位置,但取决于名称的长度,高度的值要么远离右侧,要么非常靠近左侧。有没有办法来解决这个问题?

4

2 回答 2

4

首先,对于类似的输出流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;

但是这个解决方案不是很通用。如果你的名字有 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,并在循环中迭代它Table的行以打印条目。

于 2015-11-13T13:34:49.620 回答
2
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;
于 2015-11-13T13:13:59.997 回答