Во-первых, с таким потоком вывода, как 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
в цикле для вывода записей.
person
Christian Hackl
schedule
13.11.2015