Читаем Программирование. Принципы и практика использования C++ Исправленное издание полностью

  Если хотите считать данные из файла или записать их в файл, то должны открыть поток специально для этого файла. Поток ifstream — это поток istream для чтения из файла, поток ofstream — это поток ostream для записи в файл, а поток fstream — это поток iostream, который можно использовать как для чтения, так и для записи. Перед использованием файлового потока его следует связать с файлом. Рассмотрим пример.


cout << "Пожалуйста, введите имя файла: ";

string name;

cin >> name;

ifstream ist(name.c_str); // ist — это поток ввода для файла,

                            // имя которого задано строкой name

if (!ist) error(" Невозможно открыть файл для ввода ",name);


  Определение потока ifstream с именем, заданным строкой name, открывает файл с этим именем для чтения. Функция c_str — это член класса string, создающий низкоуровневую строку в стиле языка С из объекта класса string. Такие строки в стиле языка С требуются во многих системных интерфейсах. Проверка !ist позволяет выяснить, был ли файл открыт корректно. После этого можно считывать данные из файла точно так же, как из любого другого потока istream. Например, предположим, что оператор ввода >> определен для типа Point. Тогда мы могли бы написать следующий фрагмент программы:


vector points;

Point p;

while (ist>>p) points.push_back(p);


Вывод в файлы аналогичным образом можно выполнить с помощью потоков ofstream. Рассмотрим пример.


cout << "Пожалуйста, введите имя файла для вывода: ";

string oname;

cin >> oname;

ofstream ost(oname.c_str); // ost — это поток вывода для файла,

                             // имя которого задано строкой name

if (!ost) error("Невозможно открыть файл вывода ",oname);


  Определение потока ofstream с именем, заданным строкой name, открывает файл с этим именем для чтения. Проверка !ost позволяет выяснить, был ли файл открыт корректно. После этого можно записывать данные в файл точно так же, как в любой другой поток ostream. Рассмотрим пример.


for (int i=0; i

  ost << '(' << points[i].x << ',' << points[i].y << ")\n";


Когда файловый поток выходит из пределов видимости, связанный с ним файл закрывается. Когда файл закрывается, связанный с ним буфер “очищается” (“flushed”); иначе говоря, символы из буфера записываются в файл.

Как правило, файлы в программе лучше всего открывать как можно раньше, до выполнения каких-либо серьезных вычислений. Помимо всего прочего, было бы слишком расточительным выполнить большую часть работы и обнаружить, что вы не можете ее завершить, потому что вам некуда записать результаты.

Открытие файла неявно является частью процесса создания потоков ostream и istream. В идеале при закрытии файла следует полагаться на его область видимости.

Рассмотрим пример.


void fill_from_file(vector& points, string& name)

{

  ifstream ist(name.c_str); // открываем файл для чтения

  if (!ist) error("Невозможно открыть файл для ввода",name);

    // ...используем поток ist...

    // файл неявно закроется, когда мы выйдем из функции

}


  Кроме того, можно явно выполнить операции open и close (раздел B.7.1). Однако ориентация на область видимости минимизирует шансы того, что вы попытаетесь использовать файловый поток до того, как файл будет связан с потоком, или после того, как он был закрыт. Рассмотрим пример.


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);  // открываем файл для ввода

Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже