На этом шаге мы рассмотрим использование перечисленных параметров при использовании форматного ввода-вывода.
Функции width() и fill() определяют ширину поля и заполнитель (таблица 1).
Функция | Описание |
---|---|
width() | Возвращает текущую ширину поля |
width(val) | Задает ширину поля равной val и возвращает предыдущую ширину поля |
fill() | Возвращает текущий заполнитель |
fill(c) | Назначает новый и возвращает предыдущий заполнитель |
При выводе функция width() определяет минимальную ширину поля. Определение относится только к следующему выводимому форматированному полю. При вызове без аргументов width() возвращает текущую ширину поля. При вызове с целочисленным аргументом функция width() изменяет ширину поля и возвращает ее предыдущее значение. По умолчанию минимальная ширина равна 0; это означает, что размер поля может быть произвольным. Такое значение устанавливается после вывода.
Ширина поля не может использоваться для сокращения вывода. То есть максимальную ширину поля задать невозможно. Вместо этого ее придется самостоятельно запрограммировать, например, записав данные в строку и ограничив вывод определенным количеством символов.
Функция fill() определяет символ, используемый для заполнения промежутков между отформатированным представлением величины и позицией, отмечающей минимальную ширину поля. По умолчанию заполнителем является пробел.
Тип выравнивания данных внутри поля определяется тремя флагами, перечисленными в таблице 2. Эти флаги определяются в классе ios_base вместе с соответствующей маской.
Маска | Флаг | Описание |
---|---|---|
adjustfield | left | Выравнивание по левому краю |
right | Выравнивание по правому краю | |
internal | Выравнивание знака по левому краю, а значения - по правому краю | |
нет | Выравнивание по правому краю (по умолчанию) |
После выполнения любой операции форматированного ввода-вывода восстанавливается ширина поля по умолчанию. Заполнитель и тип выравнивания остаются без изменений до тех пор, пока они ие будут модифицированы явно.
В таблице 3 показаны результаты применения разных флагов. В качестве заполнителя используется символ подчеркивания.
Флаг | width() | -42 | 0.12 | "Q" | 'Q' |
---|---|---|---|---|---|
left | 6 | -42___ | 0.12__ | Q_____ | Q_____ |
right | 6 | ___-42 | __0.12 | _____Q | _____Q |
internal | 6 | -___42 | __0.12 | _____Q | _____Q |
В ходе стандартизации были изменены правила выравнивания отдельных символов. До стандартизации при выводе отдельных символов ширина поля игнорировалась. Она использовалась при следующей операции форматированного вывода, в которой выводился не одиночный символ. Ошибка была исправлена, но это привело к нарушению совместимости с программами, в которых эта особенность использовалась.
В таблице 4 перечислены манипуляторы, изменяющие ширину поля, заполнитель и тип выравнивания.
Манипулятор | Описание |
---|---|
setw(val) | Устанавливает ширину поля при вводе и выводе равной val (соответствует функции width()) |
seffill(c) | Назначает заполнителем символ с (соответствует функции fill()) |
left | Устанавливает выравнивание по левому краю |
right | Устанавливает выравнивание по правому краю |
internal | Устанавливает выравнивание знака по левому краю, а значения - по правому краю |
Манипуляторам setw() и setfill() должен передаваться аргумент, поэтому для их использования в программу необходимо включить заголовочный файл <iomanip>. Например, рассмотрим такой фрагмент:
#include <iostream> #include <iomanip> . . . . . std::cout << std::setw(8) << std::setfill('_') << -3.14 << ' ' << 42 << std::endl; std::cout << std::setw(8) << "sum: " << std::setw(8) << 42 << std::endl;
Этот фрагмент выводит следующий результат:
___-3.14 42 __sum:______42
Ширина поля также позволяет задать максимальное количество символов, вводимых при чтении последовательностей символов типа char*. Если значение width() отлично от 0, то из потока данных читаются не более width()-l символов.
Поскольку обычные С-строки не могут увеличиваться при чтении данных, при их чтении оператором >> всегда следует ограничивать максимальный размер ввода функциями width() или setw(). Пример:
char buffer[81]; // Чтение не более 80 символов cin >> setw(sizeof(buffer)) >> buffer;
Функция читает не более 80 символов, хотя sizeof(buffer) возвращает 81, поскольку один символ является признаком завершения строки (он присоединяется автоматически). Обратите внимание иа распространенную ошибку:
char* s; cin >> setw(sizeof(s)) >> s; // ОШИБКА ВРЕМЕНИ ВЫПОЛНЕНИЯ
Дело в том, что s объявляется как указатель без выделения памяти под символы, поэтому sizeof(s) возвращает размер указателя вместо размера памяти, на которую он ссылается. Это одна из типичных ошибок, возникающих при работе с С-строками. Строковые классы позволяют предотвратить подобные ошибки:
string buffer;
cin >> buffer; //OK
На следующем шаге мы рассмотрим отображение знака для положительных чисел и вывод в верхнем регистре.