ifstream in_stream;
ofstream out_stream;
создают поток с именем "in_stream", являющийся объектом класса (как типа данных)
"ifstream" (input-file-stream, файловый поток ввода), и поток с именем "out_stream",
являющийся объектом класса "ofstream" (output-file-stream, файловый поток вывода).
Аналогию между потоками и обычными переменными (типа "int", "char" и т.д.) не
Следует понимать слишком буквально. Например, к потокам нельзя применять опера-
тор присваивания (например, нельзя записать "in_stream1 = in_stream2").
Подключение и отключение потоков от файлов
После создания потока его можно подключить к файлу (открыть файл) с помо-
щью функции-члена "open(...)". (В предыдущих лекциях уже использовались несколь-
Ко функций-членов потоков вывода. Например, во 2-й лекции применялись
"precision(...)" и "width(...)".) Функция "open(...)" у потоков ifstream и ofstream работает
По-разному (т.е. это полиморфная функция).
Для подключения потока ifstream с именем "in_stream" к файлу с именем
"Lecture_4.txt" надо применить следующий вызов:
|
|
in_stream.open("Lecture_4.txt");
Этот оператор подключит поток "in_stream" к началу файла "Lecture_4.txt"
(графически состояние программы после выполнения оператора показано на рис. 2).
Рис. 2. Состояние программы после подключения потока ввода к файлу.
Чтобы к файлу "Lecture_4.txt" подключить поток вывода ofstream с именем
"out_stream", надо выполнить аналогичный оператор:
out_stream.open("Lecture_4.txt");
Этот оператор подключит поток "out_stream" к файлу "Lecture_4.txt", но при
Этом прежнее содержимое файла будет удалено. Файл будет подготовлен к приему
Новых данных (рис. 3).
Рис. 3. Состояние программы после подключения потока вывода к файлу.
Для отключения потока "in_stream" от файла, к которому он подключен (для
закрытия файла), надо вызвать функцию-член "close()":
43
in_stream.close();
После этого состояние программы по отношению к файлу будет таким, как на
Рис. 4.
Рис. 4. Состояние программы после отключения потока ввода от файла.
Функция-член отключения от файла у потока вывода:
out_stream.close();
Выполняет аналогичные действия, но, дополнительно, в конец файла добавляется
служебный символ "end-of-file (маркер конца файла)". Т.о., даже если в поток вывода
не записывались никакие данных, то после отключения потока "out_stream" в файле
"Lecture_4.txt" будет один служебный символ (рис. 5). В таком случае файл
"Lecture_4.txt" останется на диске, но он будет пустым.
Рис. 5. Состояние программы после отключения потока вывода от файла, в
Который не было записано ни одного символа..
Проверка ошибок выполнения файловых операций
Файловые операции, например, открытие и закрытие файлов, известны как
|
|
Один из наиболее вероятных источников ошибок. В надежных коммерческих про-
Граммах всегда выполняется проверка, успешно или нет завершилась файловая опе-
Рация. В случае ошибки вызывается специальная функция-обработчик ошибки.
Простейший способ проверки ошибок файловых операций заключается в вызо-
ве функции-члена "fail()". Вызов
in_stream.fail();
возвращает истинное значение (True), если последняя операция потока "in_stream"
Привела к ошибке (может быть, была попытка открытия несуществующего файла).
После ошибки поток "in_stream" может быть поврежден, поэтому лучше не продол-
Жать работу с ним.
В приведенном ниже фрагменте программы в случае ошибки при открытии
Файла на экран выдается сообщение и программа завершает работу с помощью биб-
лиотечной функции "exit()" (она описана в файле "stdlib.h"):
#include <iostream.h>
#include <fstream.h>
#include <stdlib.h>
Int main()
{
44
ifstream in_stream;
in_stream.open("Lecture_4.txt");
If (in_stream.fail())
{
cout << "Извините, открыть файл не удалось!\n";
exit(1);
}
...
Символьный ввод/вывод
4.1 Функция ввода "get(...)"
После того, как файл для ввода данных открыт, из него можно считывать от-
дельные символы. Для этого служит функция "get(...)". У нее есть параметр типа
"char&". Если программа находится в состоянии, как на рис. 2, то после вызова:
in_stream.get(ch);
произойдет следующее: (а) переменной "ch" будет присвоено значение "'Л'", и (б) по-
ток "in_stream" будет подготовлен для чтения следующего символа (рис. 6).
Рис. 6. Состояние программы после чтения из файла первого символа.
4.2 Функция вывода "put(...)"
С помощью потока вывода класса ofstream в открытый файл можно записы-
вать отдельные символы. Для этого у класса ofstream есть функция-член "put(...)".
Записываемый символ передается ей как параметр типа "char". Если программа пре-
Бывает в состоянии, представленном на рис. 3, то оператор
out_stream.put('Л');
изменит состояние на то, которое показано на рис. 7:
Рис. 7. Состояние программы после записи в файл первого символа.
4.3 Функция "putback(...)"
В Си++ у потока ifstream есть функция-член "putback(...)". На самом деле
она не "возвращает символ назад" (т.е. не изменяет содержимого файла ввода), но ве-
Дет себя так, как будто это делает. На рис. 8 показано состояние, в которое перейдет
программа из состояния рис. 6 после выполнения оператора:
45
in_stream.putback(ch);
Рис. 8. Состояние программы после вызова функции "putback('Л')".
"Вернуть назад" можно любой символ. Состояние программы после вызова
in_stream.putback('7');
Показано на рис. 9.
Рис. 9. Состояние программы после вызова функции "putback('7')".
Проверка достижения конца файла при операциях ввода
5.1 Проверка конца файла с помощью функции "eof()"
При работе с потоком ввода надо следить за тем, чтобы не пропустить момент
достижения конца файла. В большинстве реализаций Си++ (в том числе и в Microsoft
Visual C++) в класс "поток ввода" встроен флаг "конец файла (end-of-file, EOF)" и
функция-член "eof()" для чтения этого флага. С помощью функции "eof()" можно