Программирование. Принципы и практика использования C++ Исправленное издание, стр. 141
ifstream ifs;// ...ifs >> foo; // не выполнено: для потока its не открыт ни один файл// ...ifs.open(name,ios_base::in); // открываем файл, имя которого задано // строкой name// ...ifs.close(); // закрываем файл// ...ifs >> bar; // невыполнено: файл, связанный с потоком ifs, закрыт// ...В реальной программе возникающие проблемы, как правило, намного труднее. К счастью, мы не можем открыть файловый поток во второй раз, предварительно его не закрыв. Рассмотрим пример.
fstream fs;fs.open("foo", ios_base::in); // открываем файл для ввода // пропущена функция close()fs.open("foo", ios_base::out); // невыполнено: поток ifs уже открытif (!fs) error("невозможно");Не забывайте проверять поток после его открытия.
Почему допускается явное использование функций
open()close()iostreamКак будет показано в главе 11, о файлах можно сказать намного больше, но сейчас нам достаточно того, что их можно использовать в качестве источников и адресатов данных. Это позволяет нам писать программы, которые были бы нереалистичными, если бы предложили пользователю непосредственно вводить с клавиатуры всю входную информацию. С точки зрения программиста большое преимущество файла заключается в том, что мы можем снова прочитать его в процессе отладки, пока программа не заработает правильно.
10.5. Чтение и запись файла
Посмотрим, как можно было бы считать результаты некоторых измерений из файла и представить их в памяти. Допустим, в файле записана температура воздуха, измеренная на метеостанции.
0 60.71 60.62 60.33 59.22...Этот файл содержит последовательность пар (час, температура). Часы пронумерованы от
023Представим информацию в виде структуры
Readingstruct Reading { // данные о температуре воздуха int hour; // часы после полуночи [0:23] double temperature; // по Фаренгейту Reading(int h, double t) :hour(h), temperature(t) { }};В таком случае данные можно считать следующим образом:
vector<Reading> temps; // здесь хранится считанная информацияint hour;double temperature;while (ist >> hour >> temperature) { if (hour < 0 || 23 <hour) error("Некорректное время"); temps.push_back(Reading(hour,temperature));}Это типичный цикл ввода. Поток
istreamistifstreamcinistreamistreamististreamЗаписать данные в файл обычно проще, чем считать их оттуда. Как и прежде, как только поток проинициализирован, мы не обязаны знать, что именно он собой представляет. В частности, мы можем использовать выходной файловый поток (
ofstreamostreamНапример, мы могли бы пожелать, чтобы на выходе каждая пара была заключена в скобки.
for (int i=0; i<temps.size(); ++i) ost << '(' << temps[i].hour << ',' << temps[i].temperature << ")\n";Затем итоговая программа прочитала бы исходные данные из файла и создала новый файл в формате (час, температура).
#include "std_lib_facilities.h"struct Reading { // данные о температуре воздуха int hour; // часы после полуночи [0:23] double temperature; // по Фаренгейту Reading(int h, double t):hour(h), temperature(t) { }};