Не из лекции
Заголовка
<iomanip>в материалах первого занятия нет вовсе: ни в лонгриде, ни в коде. Страница написана «на вырост» — материал верный и в задачах пригодится, но на контрольные вопросы курса по L01 он не отвечает. Из манипуляторов на занятии встречался толькоstd::boolalpha— см. Потоки ввода и вывода.
Манипуляторы из <iomanip> управляют тем, как поток
печатает значение: ширина поля, символ-заполнитель, количество знаков после
запятой.
#include <iomanip>
#include <iostream>
int main() {
std::cout << std::setfill('0') << std::setw(2) << 7 << '\n'; // 07
return 0;
}Главное правило: одни манипуляторы липкие, другие нет
std::setw действует ровно на один следующий вывод и сбрасывается:
std::cout << std::setw(4) << 1 << 2 << '\n'; // " 12", а не " 1 2"Все остальные — setfill, setprecision, fixed, left, right, boolalpha —
липкие: заданы один раз и действуют до отмены.
std::cout << std::setfill('0'); // теперь всегда нули
std::cout << std::setw(2) << 5 << ':'
<< std::setw(2) << 7 << '\n'; // 05:07 — setw пишем дваждыЭто первая причина, почему форматированный вывод «съезжает»: setw забыли
повторить.
Числа с дробной частью
double value = 3.14159;
std::cout << std::setprecision(3) << value << '\n'; // 3.14
std::cout << std::fixed << std::setprecision(3) << value << '\n'; // 3.142Без std::fixed аргумент setprecision означает количество значащих цифр,
вместе с std::fixed — количество знаков после точки. Разница проявляется
на числах вроде 0.00123, и её регулярно путают.
Оба манипулятора липкие: выставив std::fixed, вы меняете формат всего
дальнейшего вывода вещественных чисел.
Выравнивание
std::cout << std::left << std::setw(10) << "имя" << "|\n"; // имя |
std::cout << std::right << std::setw(10) << "имя" << "|\n"; // имя|По умолчанию числа и строки прижимаются вправо.
Тонкости
setwне обрезает: если значение длиннее ширины, оно печатается целиком, таблица разъезжается.setfillпринимаетchar:'0', а не"0".- Ширину и заполнитель задают до значения, а не после — манипулятор влияет на то, что идёт следом.
<iomanip>нужно подключать отдельно от<iostream>, см. Подключение заголовков.
Частые ошибки
- Один
setwна несколько значений — сработает только на первом. setprecisionбезfixedтам, где нужны именно знаки после точки.- Попытка выровнять вывод пробелами вручную вместо
setw— ломается на числах другой длины.