
- •ПРЕДОПРЕДЕЛЕННЫЕ ПОТОКИ
- •ПРЕИМУЩЕСТВА БИБЛИОТЕКИ ПОТОКОВ C++
- •Безопасность типов
- •Расширяемость для новых типов
- •Простота и последовательность
- •ОПЕРАЦИИ ПОМЕЩЕНИЯ И ИЗВЛЕЧЕНИЯ ИЗ ПОТОКА
- •Оператор помещения в поток
- •Оператор извлечения из потока
- •ФОРМАТИРОВАНИЕ ПОТОКА
- •Форматирующие функции-члены
- •Флаги форматирования
- •Манипуляторы ввода-вывода
- •ФАЙЛОВЫЙ ВВОД-ВЫВОД С ИСПОЛЬЗОВАНИЕМ ПОТОКОВ
- •НЕФОРМАТИРУЕМЫЙ ВВОД-ВЫВОД
- •Функции ввода-вывода
- •Файлы с произвольным доступом
- •Опрос и установка состояния потока
- •Перегрузка операторов извлечения и вставки
- •Переадресация ввода-вывода
Лекция 10 |
Потоковый ввод-вывод |
8 |
dec |
устанавливает флаг dec; |
|
hex |
устанавливает флаг hex; |
|
oct |
устанавливает флаг oct; |
|
Setbase ( int base ) |
задает основание системы счисления для целых; |
|
Setfill ( charT c ) |
устанавливает символ-заполнитель; |
|
Setprecision ( int n ) |
устанавливает точность чисел с плавающей точкой; |
|
setw ( int n ) |
устанавливает минимальную ширину поля; |
|
Setiosflags ( ios_base :: fmtflags mask ) |
Устанавливает ios-флаги, в соответствии с mask; |
|
Resetiosflags ( ios_base :: fmtflags mask ) |
Сбрасывает ios-флаги, в соответствии с mask. |
|
Манипуляторы ввода имеют следующее назначение: |
||
noskipws |
сбрасывает флаг skipws; |
|
skipws |
устанавливает флаг skipws; |
|
ws |
устанавливает пропуск символов-заполнителей. |
За исключением setw ( ), все изменения в потоке, внесенные манипулятором, сохраняются до следующей установки.
При внимательном изучении таблицы можно заметить, что манипуляторы охватывают функциональные возможности, предоставляемые обычными функциями-членами и флагами форматирования. В частности, манипулятор setiosflags ( ) реализует те же функциональные возможности, что и функция-член setf ( ), а манипулятор resetiosflags ( ) – те же, что и функция-член unsetf ( ).
Для доступа к манипуляторам с параметрами необходимо включить в программу стандартный заголовочный файл <iomanip>. При использовании манипулятора без параметров скобки за ним не ставятся, так как на самом деле он представляет собой указатель на функцию-член, который передается перегруженному оператору <<.
Рассмотрим пример, демонстрирующий использование манипуляторов.
#include <iostream.h> #include <iomanip.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 << setw ( 4 ) << x << ’\t’ ;
cout << setw ( 6 ) << sqrt ( x ) << ’\t’ ; cout << setw ( 3 ) << x*x << ' \n ' ;
}
}
Этот пример функционально полностью эквивалентен примеру, приведенному ранее, но для управления форматом вывода использует манипуляторы, а не функции форматирования.
ФАЙЛОВЫЙ ВВОД-ВЫВОД С ИСПОЛЬЗОВАНИЕМ ПОТОКОВ
Для осуществления операций с файлами библиотека ввода-вывода предусматривает три класса: ifstream, ofstream и fstream. Эти классы являются производными, соответственно, от классов istream, ostream и iostream. Поскольку эти последние классы, в свою очередь, являются производными от класса ios, классы файловых потоков наследуют все функциональные возможности своих родителей (перегруженные операции << и >> для встроенных типов, функции и флаги форматирования, манипуляторы и пр.). Для реализации файлового ввода-вывода нужно включить в программу заголовочный файл <fstream.h>.
Существует небольшое отличие между использованием предопределенных и файловых потоков. Файловый поток должен быть связан с файлом прежде, чем его можно будет использовать. С другой стороны, предопределенные потоки могут использоваться сразу после запуска программы, даже в конструкторах статических классов, которые выполняются даже раньше вызова функции main ( ). Вы можете позиционировать файловый поток в произвольную позицию в файле, в то время как для предопределенных потоков это обычно не имеет смысла.
Выжол Ю.А. |
Объектно-ориентированное программирование |
Лекция 10 |
Потоковый ввод-вывод |
9 |
Для создания файлового потока эти классы предусматривают следующие формы конструктора: создать поток, не связывая его с файлом:
explicit ifstream ( ) ; explicit ofstream ( ) ; explicit fstream ( ) ;
создать поток, открыть файл и связать поток с файлом:
explicit ifstream ( const char*name , ios :: openmode mode = ios :: in ) ;
explicit ofstream ( const char* name , ios :: openmode mode = ios :: out | ios :: trunc ) ; explicit fstream ( const char* name , ios :: openmode mode = ios :: in | ios :: out ) ;
Чтобы открыть файл для ввода или вывода, можно использовать вторую форму нужного конструктора fstream fs ("FileName.dat") ;
или вначале создать поток с помощью первой формы конструктора, а затем открыть файл и связать поток с открытым файлом, вызвав функцию-член ореn ( ). Эта функция определена в каждом из классов потокового ввода-вывода и имеет следующие прототипы:
void ifstream :: open ( const char*name , ios :: openmode mode = ios :: in ) ;
void ofstream :: open ( const char* name , ios :: openmode mode = ios :: out | ios :: trunc ) ; void fstream :: open ( const char* name , ios :: openmode mode = ios :: in | ios :: out ) ;
Здесь name – имя файла, mode – режим открытия файла. Параметр mode является перечислением и может принимать следующие значения:
ios :: in |
открыть файл для чтения; |
ios :: out |
открыть файл для записи; |
ios :: ate |
начало вывода устанавливается в конец файла; |
ios :: app |
скрыть файл для добавления в конец; |
ios :: trunc |
усечь файл, т.е. удалить его содержимое; |
ios :: binary |
двоичный режим операций. |
Режимы открытия файла представляют собой битовые маски, поэтому вы можете задавать два или более режима, объединяя их операцией ИЛИ. В следующем фрагменте кода файл открывается для вывода с помощью функции open ( ):
ofstream ofs ;
ofs.open ("FileName.dat") ;
Обратите внимание, что по умолчанию режим открытия файла соответствует типу файлового потока. У потока ввода или вывода флаг режима всегда установлен неявно. Например, для потока вывода в режиме добавления файла можно вместо инструкции
ofstream ofs ("FName.txt", ios :: out | ios :: app ) ;
написать следующую:
ofstream ofs ("FName.txt", ios :: app ) ;
Между режимами открытия файла ios :: ate и ios :: app имеется небольшая разница.
Если файл открывается в режиме добавления, весь вывод в файл будет осуществляться в позицию, начинающуюся с текущего конца файла, безотносительно к операциям позиционирования в файле. В режиме открытия ios :: ate (от англ, "at end" ) вы можете изменить позицию вывода в файл и осуществлять запись, начиная с нее. Для потоков вывода режим открытия эквивалентен ios :: out | ios :: trunc, то есть вы можете опустить режим усечения файла. Однако для потоков ввода-вывода его нужно указывать явно. Файлы, которые открываются для вывода, создаются, если они еще не существуют.
Если открытие файла завершилось неудачей, объект, соответствующий потоку в булевом выражении, будет возвращать false:
if ( ! osf ) cout << "File not open\п" ;
Проверить успешность открытия файла можно также с помощью функции-члена is_open ( ), имеющей следующий прототип:
bool is_open ( ) const ;
Функция возвращает true, если поток удалось связать с открытым файлом. Например, if ( ! osf.is_open ( )) cout << "File not open\п" ;
Если при открытии файла не указан режим ios :: binary, файл открывается в текстовом режиме и после того, как файл успешно открыт, для выполнения операций ввода-вывода можно использовать операторы извлечения и вставки в поток. Можно даже использовать функции ввода-вывода, принятые в языке
Выжол Ю.А. |
Объектно-ориентированное программирование |