Использование файлов для ввода и вывода данных
Потоки C++ обеспечивают универсальные методы обработки данных, поступающих с клавиатуры или диска, а также выводимых на экран и диск. В любом случае можно использовать либо операторы ввода и вывода, либо другие стандартные функции и манипуляторы. Дальнейшие разделы главы посвящены операциям открытия и закрытия файлов, которые сопровождаются созданием объектов ifstream и ofstream.
Объекты ofstream
Объекты, создаваемые для считывания или записи данных в файл, называются ofstream. Они являются производными от уже знакомого вам класса iostream.
Чтобы приступить к записи в файл, нужно сначала создать объект ofstream, а затем связать его с определенным файлом на диске. Использование объектов ofstream требует включения в программу файла заголовка fstream.h.
Примечание: Поскольку fstream содержит в себе iostream.h, нет необходимости в отдельном включении файла iostream.h.
Состояния условий
Объектами iostream поддерживаются флаги, отражающие состояние ввода и вывода. Значение каждого из этих флагов можно проверить с помощью функций, возвращающих TRUE или FALSE: eof(), bad(), fail() и good(). Функция eof() возвращает значение TRUE, если в объекте iostream встретился символ EOF (end of file — конец файла). Функция bad() возвращает значение TRUE при попытке выполнить ошибочную операцию. Функция fail() возвращает значение TRUE каждый раз, когда это же значение возвращает функция bad(), а также в тех случаях, когда операция невыполнима в данных условиях. Наконец, функция good() возвращает значение TRUE, когда все идет хорошо, т.е. все. остальные функции возвращают значение FALSE.
Открытие файлов для ввода-вывода
Для открытия файла myfile.cpp с помощью объекта ofstream нужно объявить экземпляр этого объекта, передав ему в качестве параметра имя файла:
ofstream fout("myfile.cpp");
Открытие файла для ввода выполняется аналогичным образом, за тем исключением, что для этого используется объект ifstream:
ifstream fin("myfile.cpp");
Обратите внимание, что в выражениях задаются имена объектов fout и fin, которые можно использовать так же, как объекты cout и cin соответственно.
Очень важным методом, используемым в файловых потоках, является функция-член close(). Каждый создаваемый вами объект файлового потока открывает файл для чтения или записи (или и для того и другого сразу). По завершении работы файл необходимо закрыть с помощью функции close(), чтобы впоследствии не повредить его и записанные в нем данные.
После связывания объектов потока с соответствующими файлами их можно использовать так же, как остальные объекты ввода-вывода. Пример использования объектов для обмена данными с файлами показан в листинге 16.16.
Листинг 16.16. Открытие файла для чтения и записи
1: #include <fstream.h>
2: int main()
3: {
4: char fileName[80];
5: char buffer[255]; // для ввода данных пользователем
6: cout << "File паше: ";
7: cin >> fileName;
8:
9: ofstream fout(fileName); // открытие файла для записи
10: fout << "This line written directly to the file...\n";
11: cout << "Enter text for the file: ";
12: cin.ignore(1,'\n'); // пропускает символ разрыва строки после имени файла
13: cin.getline(buffer,255); // принимает данные, введенные пользователем,
14: fout << buffer << "\n"; // и записывает их в файл
15: fout.close(); // закрывает файл, после чего его вновь можно открыть
16:
17: ifstream fin(fileName); // открывается тот же файл для чтения
18: cout << "Here's the contents of the file:\n";
19: char ch;
20: while (fin.get(ch))
21: cout << ch;
22:
23: cout << "\n*** End of file contents.***\n";
24:
25: fin.close(); // не забудь закрыть файл в конце программы
26: return 0;
27: }
Результат:
File name: test1
Enter text for the file: This text is written to the file!
Here's the contents of the file: This line written directly to the file...
This text is written to the file!
***End of file contents.***
Анализ: В строке 4 создается массив для записи имени файла, а в строке 5 — еще один массив для временного хранения информации, вводимой пользователем. В строке 6 пользователю предлагается ввести имя файла, которое записывается в массив fileName. В строке 9 создается объект ofstream с именем fout, который связывается с введенным ранее именем файла. В результате происходит открытие файла. Если файл с таким именем уже существует, содержащаяся в нем информация будет замещена.
Строкой 10 введенный текст записывается прямо в файл, а в строке 11 пользователю вновь предлагается ввести новый текст. Символ разрыва строки, оставшийся в буфере после ввода имени файла, удаляется строкой 12, после чего все введенные пользователем данные записываются в массив в строке 13. Введенный текст записывается в файл вместе с символом разрыва строки, а затем в строке 15 этот файл закрывается.
В строке 17 файл открывается заново, но в этот раз для чтения, и его содержимое посимвольно вводится в программу в строках 20—21.