2015-11-13 2 views
3

Так что я только начинаю изучать C++, и я интересно, если его путь к формиат ваш выход с соиЬ так он будет выглядеть красиво и структурированы в колонкахC++ колонны установки с использованием соиЬ

, например.

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 

проблема, которую я пытаюсь решить, что я хочу, чтобы разместить высоту в определенной позиции от имени, но в зависимости от того, какая длина имени я беру, значение высоты либо удаляется вправо, либо будет очень близко к левому. Есть ли способ исправить это?

ответ

3

Прежде всего, с выходным потоком, как 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 «s в цикле в порядке для печати записей.

+0

Вы должны добавить '' Name ''в' first_column_entries'. 'fname +" "+ lname' и' fname2 + "" + lname2' могут привести к одному пробелу ... –

+0

@SimonKraemer: Хорошая точка. Я воздержался от публикации полной программы, но это изменение имеет смысл. –

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; 
Смежные вопросы