Ошибки потоков
Каждый поток (istream или ostream) имеет ассоциированное с ним состояние, с помощью проверки которого осуществляется обработка ошибок и нестандартных условий.
Поток может находиться в одном из следующих состояний:
enum stream_state { _good, _eof, _fail, _bad };
Если состояние _good или _eof, последняя операция ввода прошла успешно, а если – _good, то следующая операция ввода может пройти успешно, в противном случае она закончится неудачей. Другими словами, применение операции ввода к потоку, который не находится в состоянии _good, является пустой операцией. Состояние потока можно проверять, например, так:
switch (cin.rdstate()) {
case _good: // последняя операция над cin прошла успешно
break;
case _eof: // конец файла
break;
case _fail: // некоего рода ошибка форматирования
break;
case _bad: // возможно, символы cin потеряны
break; }
Файловый ввод-вывод с применением потоков С++
В С++ существуют классы потоков ввода-вывода, определенные в соответствующей библиотеке:
ios //базовый потоковый класс
streambuf //буферизация потоков
istream //потоки ввода
ostream //потоки вывода
iostream //двунаправленные потоки
istrstream //строковые потоки ввода
ostrstream //строковые потоки вывода
strstream //двунаправленные строковые потоки
ifstream //файловые потоки ввода
ofstream //файловые потоки вывода
fstream //двунаправленные файловые потоки
Стандартные потоки (istream,ostream,iostream) служат для работы с терминалом. Строковые потоки (istrstream, ostrstream, strstream) – для ввода-вывода из строковых буферов, размещенных в памяти, файловые потоки (ifstream, ofstream, fstream) – для работы с файлами.
Для реализации файлового ввода-вывода небходимо включить заголовочный файл fstream.h, содержащий производные от istream и ostream классы ifstream,ofstream и fstream,и объявить соответствующие объекты. Например:
ifstream in;//ввод
ofstream out;//вывод
fstream io;//ввод - вывод
Файловые потоки можно определить с помощью конструкторов:
ofstream obj (filename, mode),
ifstream obj (filename, mode),
где mode может иметь следующие значения:
ios::app //запись в конец существующего файла
ios::ate //после открытия файла перейти в его конец
ios::binary /*открыть файл в двоичном режиме (по умолчанию – текстовый) */
ios::in //открыть для чтения
ios::nocreate //сообщать о невозможности открытия, если файл не существует
ios::noreplace //сообщать о невозможности открытия, если файл существует
ios::out //открыть для вывода
ios::trunc //если файл существует, стереть содержимое
При необходимости изменения способа открытия или применения файла можно при создании файлового потока использовать два или более флагов: ios::app|ios::noreplace
Для открытия файла одновременно для чтения и записи используются объекты класса fstream:
fstream obj(filename, ios::in|ios::app);
После объявления потоков открытие файла, связывающее его с потоком, можно производить не через конструктор, а с помощью метода open():
void open (char *filename,int mode,int access),где filename – имя файла, включающее путь; mode – режим открытия файла, access – доступ. Параметр аccess принимает следующие значения: 0 – файл со свободным доступом, 1 –только для чтения, 8 – архивный файл. Например:
ofstream out;
out.open(“test.dat”,ios::out,0);
Параметры можно задать по умолчанию.
оut.open(“test.dat”);//будет то же самое
При завершении программы открытые файлы неявно закрываются. Для явного закрытия объектов файловых потоков применяется метод close().