C++ Beginner: как мне предотвратить, чтобы текст в моей таблице выдвигал любой текст справа от него?
Я работаю над очень простой программой для своего класса по основам, и у меня все на 98% работает так, как задумано.
Эта программа берет имена трех классов, усредняет их и выводит их в таблицу, но так как assignmentName[]
находится на той же строке кода, что и grade[]
это толкает grade[]
вправо, определяя, сколько символов введено пользователем. Скриншот проблемы
Вот код, который я сейчас написал для таблицы:
cout << "___________________________\n";
cout << name << "'s Grade Chart\n";
cout << "---------------------------\n";
cout << setprecision(1) << fixed;
cout << "Grade for " << assignmentName[0] << setw(8) << grade[0] << endl;
cout << "Grade for " << assignmentName[1] << setw(8) << grade[1] << endl;
cout << "Grade for " << assignmentName[2] << setw(8) << grade[2] << endl;
cout << "\nYour average grade between those three assignments is: " << setw(1) << avg << endl;`
2 ответа
Я прокомментировал: "Поместите другой setw(N)
где N немного больше, чем самый большой assignmentName
перед каждым << assignmentName
".
Но, если подумать, это немного веселее, поэтому я считаю, что реальный ответ в порядке.
Во-первых, некоторые материалы для чтения:
Документация по std::left
а также std::right
Документация по std::max
А теперь о шоу!
Сначала нам нужно узнать, насколько велико имя самого большого назначения.
size_t max = 0;
for (const string & assn: assignmentName)
{
max = std::max(max, assn.length());
// You may need
//max = std::max(max, strlen(assn));
// if you've been forced to resort to barbarism and c-style strings
}
max++; // one extra character just in case we get a really long grade.
Иногда это может стать намного аккуратнее. Например std::max_element
может устранить необходимость в цикле, который мы использовали для получения максимальной длины имени присваивания. В этом случае мы ищем размер строки, а не лексический порядок строки, поэтому я думаю, что цикл и std::max
немного легче на мозг.
А теперь, чтобы отформатировать, мы печатаем имена, выровненные по левому краю и выровненные по правому краю, с дополненными max
персонажи и оценки 8 символов.
cout << "Grade for " << std::left << setw(max) << assignmentName[0]
<< std::right << setw(8) << grade[0] << '\n'
<< "Grade for " << std::left << setw(max) << assignmentName[1]
<< std::right << setw(8) << grade[1] << '\n'
<< "Grade for " << std::left << setw(max) << assignmentName[2]
<< std::right << setw(8) << grade[2] << '\n';
Обратите внимание, что теперь это один большой cout
, Это было сделано в основном для демонстрационных целей и потому что я думаю, что это выглядит лучше. Это на самом деле не сильно сэкономит вам, во всяком случае, время обработки. Что экономит время, так это отсутствие endl
s. endl
на самом деле это очень дорогая операция, потому что она не только завершает строку, но и сбрасывает. Он передает все, что было буферизовано в потоке, на базовый носитель, в данном случае консоль. Компьютеры в своих лучших проявлениях, когда они могут фактически избежать выхода из компьютера, пока они действительно не должны. Рисование на экране намного дороже, чем запись в ОЗУ или в кэш, так что не делайте этого, пока не потребуется.
Вместо того чтобы писать:
"Grade for " << assignmentName[x] << setw[y] << grade(z)
Написать:
"Grade for " << setw[a] << assignmentName[x] << setw[y] << grade(z)
Где а больше х в каждом случае. Может быть, это должно исправить это.
Ваше a должно быть примерно 10 или 15 или что-то в этом роде. Я надеюсь, что это работает после этого. Попытайся.