
- •ПРЕДОПРЕДЕЛЕННЫЕ ПОТОКИ
- •ПРЕИМУЩЕСТВА БИБЛИОТЕКИ ПОТОКОВ C++
- •Безопасность типов
- •Расширяемость для новых типов
- •Простота и последовательность
- •ОПЕРАЦИИ ПОМЕЩЕНИЯ И ИЗВЛЕЧЕНИЯ ИЗ ПОТОКА
- •Оператор помещения в поток
- •Оператор извлечения из потока
- •ФОРМАТИРОВАНИЕ ПОТОКА
- •Форматирующие функции-члены
- •Флаги форматирования
- •Манипуляторы ввода-вывода
- •ФАЙЛОВЫЙ ВВОД-ВЫВОД С ИСПОЛЬЗОВАНИЕМ ПОТОКОВ
- •НЕФОРМАТИРУЕМЫЙ ВВОД-ВЫВОД
- •Функции ввода-вывода
- •Файлы с произвольным доступом
- •Опрос и установка состояния потока
- •Перегрузка операторов извлечения и вставки
- •Переадресация ввода-вывода
Лекция 10 |
Потоковый ввод-вывод |
5 |
Для переменной типа char* (рассматриваемого как строка) оператор >> пропускает символызаполнители и сохраняет следующие за ними символы, пока не появится следующий символ-заполнитель. Затем в указанную переменную добавляется нуль-символ.
ФОРМАТИРОВАНИЕ ПОТОКА
До сих пор мы использовали для вывода информации во всех примерах форматы, заданные в C++ по умолчанию. Для управления форматированием библиотека ввода-вывода предусматривает три вида средств: форматирующие функции, флаги и манипуляторы. Все эти средства являются членами класса basic_ios и потому доступны для всех потоков.
Форматирующие функции-члены
Рассмотрим вначале форматирующие функции-члены. Их всего три: width ( ), precision ( ) и fill ( ).
По умолчанию при выводе любого значения оно занимает столько позиций, сколько символов выводится. Функция width ( ) позволяет задать минимальную ширину поля для вывода значения. При вводе она задает максимальное число читаемых символов. Если выводимое значение имеет меньше символов, чем заданная ширина поля, то оно дополняется символами-заполнителями до заданной ширины (по умолчанию – пробелами). Однако если выводимое значение имеет больше символов, чем ширина отведенного ему поля, то поле будет расширено до нужного размера. Эта функция имеет следующие прототипы:
streamsize width ( streamsize wide ) ; streamsize width ( ) const ;
Тип streamsize определен в заголовочном файле <iostream.h> как целочисленный. Функция с первым прототипом задает ширину поля wide, а возвращает предыдущее значение ширины поля. Функция со вторым прототипом возвращает текущее значение ширины поля. По умолчанию она равна нулю, то есть вывод не дополняется и не обрезается. В ряде компиляторов после выполнения каждой операция вывода значение ширины поля возвращается к значению, заданному по умолчанию.
Функция precision ( ) позволяет узнать или задать точность (число выводимых цифр после запятой), с которой выводятся числа с плавающей точкой. По умолчанию числа с плавающей точкой выводятся с точностью, равной шести цифрам. Функция имеет precision ( ) следующие прототипы:
streamsize precision ( streamsize prec ) ; streamsize precision ( ) const ;
Функция с первым прототипом устанавливает точность равной ргес и возвращает предыдущую точность. Функция со вторым прототипом возвращает текущую точность.
Замечание. Если не установлен флаг scientific или fixed (оба эти флага рассматриваются далее), то precision ( ) задает общее число цифр.
Функция fill ( ) позволяет прочесть или установить символ-заполнитель. Она имеет следующие прототипы:
char_type fill ( char_type ch ) ; char_type fill ( ) const ;
Функция с первым прототипом устанавливает ch в качестве текущего символа-заполнителя и возвращает предыдущий символ-заполнитель. Функция со вторым прототипом возвращает текущий символзаполнитель. По умолчанию в качестве символа-заполнителя используется пробел. Тип данных char_type является параметром класса basic_ios и может обозначать набор "узких" или "широких" символов.
Рассмотрим пример программы, в котором используются форматирующие функции:
#include <iostream.h> #include <math.h> void main ( )
{
double x ; cout.precision ( 4 ) ; cout.fill ( '0' ) ;
cout << "x\tsqrt(x)\tх^2\n" ; for ( x = l.0 ; x<=6 . 0 ; x++ )
{
cout. width (4) ; cout << x << ’\t’ ; cout.width ( 6 ) ;
Выжол Ю.А. |
Объектно-ориентированное программирование |
Лекция 10 |
Потоковый ввод-вывод |
6 |
cout << sqrt ( x ) << ’\t’ ; cout.width ( 3 ) ;
cout << x*x << ' \n ' ;
}
}
Эта программа выводит на экран небольшую таблицу значений переменной х, ее квадратного корня и квадрата:
x |
sqrt(x) |
x^2 |
0001 |
0000001 |
001 |
0002 |
001.414 |
004 |
0003 |
001.732 |
009 |
0004 |
002.000 |
016 |
0005 |
002.236 |
025 |
0006 |
002.449 |
036 |
Флаги форматирования
С каждым потоком связан набор флагов, которые управляют форматированием потока. Они представляют собой битовые маски, которые определены в классе ios как данные enum-типа fmt_flags. Сами флаги принадлежат типу fmtf lags, который определен следующим образом:
typedef int |
fmtflags ; |
|
Флаги форматирования имеют следующее назначение: |
||
boolalpha |
значения булевского типа вставляются и извлекаются в виде слов true и false |
|
hex |
значения целого типа преобразуются к основанию 16 (как шестнадцатеричные) |
|
dec |
значения целого типа преобразуются к основанию 10 |
|
oct |
значения целого типа преобразуются к основанию 8 (как восьмеричные) |
|
basefield = dec | oct | hex |
флаги dec, oct и hex взаимно исключают друг друга |
|
fixed |
числа с плавающей точкой выводятся в формате с фиксированной точкой |
|
scientific |
числа с плавающей точкой выводятся в научной записи (т.е., +n.хххЕ+уу) |
|
floatfield = scientific | fixed |
флаги scientific и fixed взаимно исключают друг друга |
|
showbase |
выводится основание системы счисления в виде префикса к целому числовому значе- |
|
showpoint |
нию (например, число 10FE выводится как Ох10FЕ) |
|
при выводе значений с плавающей точкой выводится десятичная точка и последующие |
||
showpos |
нули |
|
при выводе положительных числовых значений выводится знак плюс |
||
uppercase |
заменяет определенные символы нижнего регистра на символы верхнего регистра |
|
|
(символ "е" при выводе чисел в научной нотации на "Е" и символ "х" при выводе 16- |
|
left |
ричных чисел на "X") |
|
данные при выводе выравниваются по левому краю поля |
||
right |
данные при выводе выравниваются по правому краю поля |
|
internal |
добавляются символы-заполнители между всеми цифрами и знаками числа для запол- |
|
|
нения поля вывода |
adjustfield = left | right | internal флаги left и right взаимно исключают друг друга skipws
unitbuf
Прочесть текущие установки флагов позволяет функция-член flags ( ) класса ios. Для этого используется следующий прототип этой функции:
fmtflags flags ( ) const ;
Функция flags ( ) имеет и вторую форму, которая может использоваться для установки значений флагов. Для этого используется следующий прототип этой функции:
fmtflags flags ( fmtflags fmtfl ) ;
В этом случае битовый шаблон копируется fmtfl в переменную, предназначенную для хранения флагов форматирования. Функция возвращает предыдущие значения флагов. Поскольку эта форма функции меняет весь набор флагов, она применяется редко. Вместо нее используется функция-член setf ( ) класса
Выжол Ю.А. |
Объектно-ориентированное программирование |
Лекция 10 |
Потоковый ввод-вывод |
7 |
ios, которая позволяет установить значение одного или нескольких флагов. Она имеет следующие прототипы:
fmtflags setf ( fmtflags mask ) ;
fmtflags setf ( fmtflags fmtfl , fmtflags mask ) ;
Первая функция-член неявно вызывает функцию flags ( mask | flags ( )) для установки битов, указанных параметром mask, и возвращает предыдущие значения флагов. Второй вариант функции присваивает битам, указанным параметром mask, значения битов параметра fmtfl, а затем возвращает предыдущие значения флагов. Например, следующий вызов функции setf ( ) устанавливает для потока cout флаги hex
и uppercase:
cout.setf ( ios :: hex | ios :: uppercase ) ;
Сбросить установленные флаги можно с помощью функции-члена unsetf ( ) класса ios, имеющей следующий прототип:
void unsetf ( fmtflags mask ) ;
Она сбрасывает флаги, заданные параметром mask. Следующий пример демонстрирует некоторые флаги:
#include <iostream> |
|
|
void main ( ) |
|
|
{ |
|
|
double d = 1.321e9 ; |
int n = 1024 ; |
|
cout << "d = " << d << "\tn = " << n << ' \n ' ; |
// выводит значения |
|
cout.setf ( ios :: hex | ios :: uppercase ) ; |
// изменяет флаги |
|
cout.setf ( ios :: showpos ) ; |
|
|
cout << "d = " << d << "\tn = " << n << ' \n ' ; |
// выводит значения снова |
|
} |
|
|
При выполнении программа выводит на экран:
d = 1.321е+09 |
n = 1024 |
d = +1.321Е+09 |
n = +1024 |
Манипуляторы ввода-вывода
Система ввода-вывода C++ предусматривает еще один способ форматирования потока. Этот способ основан на использовании манипуляторов ввода-вывода. Манипуляторы ввода-вывода представляют собой просто вид функций-членов класса ios, которые, в отличие от обычных функций-членов, могут располагаться внутри инструкций ввода-вывода. В связи с этим ими пользоваться обычно удобнее.
Манипуляторы вывода имеют следующее назначение:
endl |
вставляет символ конца строки и очищает буфер; |
ends |
вставляет символ конца строки; |
flush |
очищает буфер потока; |
left |
устанавливает флаг left; |
right |
устанавливает флаг right; |
internal |
устанавливает флаг internal; |
fixed |
устанавливает флаг fixed; |
scientific |
устанавливает флаг scientific; |
showbase |
устанавливает флаг showbase; |
noshowbase |
сбрасывает флаг showbase; |
showpoint |
устанавливает флаг showpoint; |
noshowpoint |
сбрасывает флаг showpoint; |
showpos |
устанавливает флаг showpos; |
noshowpos |
сбрасывает флаг showpos; |
unitbuf |
устанавливает флаг unitbuf; |
nounitbuf |
сбрасывает флаг unitbuf; |
uppercase |
устанавливает флаг uppercase; |
nouppercase |
сбрасывает флаг uppercase. |
Манипуляторы ввода-вывода имеют следующее назначение:
boolalpha |
устанавливает флаг boolalpha; |
noboolalpha |
сбрасывает флаг boolalpha; |
Выжол Ю.А. |
Объектно-ориентированное программирование |