Форматирование Библиотека потоков С++ предусматривает три способа управления форматов выходных данных: вызов форматирующих функций-элементов использование флагов использование манипуляторов
1. Форматирующие функции-элементы Для чтения и установки ширины поля потока в классе ios имеется функция width ФункцияОписание int ios::width( );Возвращает текущее значение внутренней переменной ширины поля потока int ios::width(int);Устанавливает значение внутренней переменной ширины поля потока
Применяемый при вводе, метод (функция член класса) width может быть использован для задания максимального числа читаемых символов Применяемый при выводе, задает минимальную ширину поля Если ширина меньше заданной, выход заполняется дополнительными символами fill Если больше, значение width игнорируется. По умолчанию width = 0 (выход не дополняется и не обрезается) width обнуляется после каждого помещения данных в поток
Пример ограничения числа вводимых символов при вводе: #include const int MAX_LEN = 10; int main(void) { char name[MAX_LEN]; cout > name; return 0; }
Пример использования для выравнивания правого поля при выводе: #include const int FLD_LEN = 10; int main(void) { int x1=2867, y1=20051; cout.width(FLD_LEN); cout
Для чтения или изменения заполняющего символа можно применять функции ios:fill ФункцияОписание char ios:: fill( ); Возвращает текущий символ заполнения char ios::fill(char); Устанавливает символ и возвращает его предыдущее значение По умолчанию - символ заполнения пробел
Функции ios:precision могут применяться при выводе чисел с плавающей точкой ФункцияОписание int ios::precision( ); Возвращает текущее значение int ios::precision(int); Устанавливает символ и возвращает его предыдущее значение
По умолчанию точность равна 6 цифрам. Если установлен флаг scientific или fixed задается число цифр, выводимых после запятой Если эти флаги не заданы - задается общее число цифр
#include int main(void) { float f = ; double d = ; cout. precision(4); cout
2. Флаги В потоках С++ имеются флаги формата. Они задают, каким образом форматируется ввод и вывод. Флаги являются битовыми полями, хранящимися в переменной long
ФункцияОписание long ios::flags(); Возвращает текущее значение long ios::flags(long); Присваивает флагам значение и возвращает предыдущее значение long ios::setf(long,long); Присваивает флагам, биты которых установлены во втором параметре, значения соответствующих бит первого параметра. Возвращает предыдущее значение long ios::setf(long); Устанавливает флаги, биты которых установлены в параметре. Возвращает предыдущее значение long ios::unsetf(long); Сбрасывает флаги, биты которых установлены в параметре. Возвращает предыдущее значение
ФункцияПо умолчанию Описание ios::skipws xЕсли установлен, при вводе игнорируются предшествующие пробелы или эквивалентные им символы ios::left Данные при выводе выравниваются по левой границе поля ios::right xпо правой ios::internal Знак числа слева, число выравнивается по правому. Промежуток заполняется символами fill ios::dec ios::oct ios::hex Числа выводятся по основанию 10 (десятичные), 8 (восьмеричные), 16 (шестнадцатиричные) Следующая таблица описывает флаги форматирования
ios::showbase Добавляется индикатор основания 0x - 16 (шестнадцатеричные) (восьмеричные) ios::showpoint При выводе чисел типа float, double или long double показывается десятичная точка ios::uppercase Буквы A-F в шестнадцатеричных выводятся в верхнем регистре, E как показатель тоже ios::showpos Выводится знак + для положительных ios::sientific Вещественные числа выводятся с показателем E или e ios::fixed Вещественные числа выводятся с десятичной точкой ios::unitbuf Буфер освобождается после каждой операции помещения ios::stdio Потоки stdio, sterr освобождаются после каждой операции помещения
3. Манипуляторы Манипуляторы - это функции, которые можно включать в цепочку последовательных операций помещения и извлечения. За исключением setw, изменения, внесенные манипуляторами, сохраняются до следующей установки Манипуляторы, не требующие аргументов, называются простыми Предопределенные простые манипуляторы показаны в следующей таблице
МанипуляторОписание endl Помещает в выходной поток символ новой строки (\n) и вызывает манипулятор flush ends Помещает в выходной поток нулевой символ (\0) flush Принудительно записывает все выходные данные на соответствующие физические устройства dec Устанавливает основание 10 (см. ios::dec) hex Устанавливает основание 16 (см. ios::hex) oct Устанавливает основание 8 (см. ios::oct) ws Заставляет игнорировать при вводе ведущие пробельные символы(см. ios::skipws)
#include int main(void) { int i; cout > i; if (!cin) // Проверить корректность введенного { cout
МанипуляторОписание setbase(int _b); Задает преобразования в соответствии с параметром: 0 - Основание по умолчанию ричное resetiosflags(long _b); Сбрасывает флаги, биты которых установлены в параметре setiosflags(long _b) ; Устанавливает флаги, биты которых установлены в параметре setfill(int _b); Задает заполняющий символ Параметризованные манипуляторы требуют спецификации аргументов
МанипуляторОписание setprecision(int _n); Задает значение внутренней переменной точности вещественных чисел setw(int _w) ; Задает значение внутренней переменной ширины поля Для входного потока максимальное число символов, которые должны быть прочитаны Для выходного - минимальную ширину поля Если ширина меньше заданной, выход заполняется дополнительными символами fill Если больше, значение width игнорируется. Ширина поля устанавливается на 0 после каждой операции помещения
#include int main(void) { double dbls = { 1.245, , , , }; cout
Ошибки потоков Все объекты потоки происходят от класса ios и наследуют элемент данных state. Этот элемент представляет состояние потока в виде битового множества Все возможные состояния задаются классом ios, который определяется в iostream.h:
class _EXPCLASS ios { public: enum io_state { goodbit = 0x00, // нет установленных битов, все OK eofbit = 0x01, // достигнут конец файла failbit = 0x02, // последний оператор i/o ошибочный // использование потока может продолжаться, // после того как бит будет сброшен badbit = 0x04, // попытка неправильной операции // Серьезная ошибка, потоком, скорее // всего, нельзя будет пользоваться hardfail = 0x08 // невосстановимая ошибка, обычно связанная // с неисправностью оборудования }; // };
Состояния потока Существуют различные функции и операции, позволяющие читать состояние потока, а также функции для установки или очистки состояния потока
МетодОписание int rdstate(); Возвращает текущее значение int eof(); Возвращает ненулевое значение, если установлен флаг ios:eofbit int fail(); Возвращает ненулевое значение, если установлен флаг ios:failbit, ios:badbit, ios:hardfail int bad(); Возвращает ненулевое значение, если установлен флаг ios: badbit, ios:hardfail int good() Возвращает ненулевое значение, если сброшены все биты ошибок Методы опроса состояния потока
МетодОписание void clear(int=0); Если параметр =0 (по умолчанию), все биты очищаются. В противном случае параметр принимается в качестве состояния ошибки operator void*( ) Возвращает нулевой указатель, если установлен один из ios:failbit, ios:badbit, ios:hardfail (так же как fail() ) int operator!( ); Возвращает нулевое значение, если установлен один из ios:failbit, ios:badbit, ios:hardfail (так же как fail() ) Операция void*( ) всякий раз вызывается, когда поток сравнивается с нулем while (strm0bj) { // С потоком все в порядке }
ДействиеПример Проверить установлен ли flag if (strm.rdstate()&ios::flag) Сбросить flag strm.clear(rdstate() & ~ios::flag) Установить flag strm.clear(rdstate() | ios::flag) Установить flag strm.clear(ios::flag) //сбрасывает другие флаги Сбросить все флаги strm.clear() В следующей таблице приведены распространенные операции, которые можно производить с флагами потока.