Главная->Інформатика та програмування->Содержание->Форматированный файловый ввод/вывод

ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ В C++ (4-Е ИЗДАНИЕ) (часть 12) онлайн

Форматированный файловый ввод/вывод

При форматированном вводе/выводе числа хранятся на диске в виде серии сим-

волов. Таким образом, число 6,02 вместо того, чтобы храниться в виде четырех-

байтного значения типа float или восьмибайтного double, хранится в виде после-

довательности символов '6',  ',', '0', '2'. Это странно с точки зрения экономии

памяти, особенно в случае многоразрядных чисел, но зато легко применяется на

практике и в некоторых ситуациях гораздо удобнее. Слава Богу, что хоть симво-

лы и строки хранятся в файлах в более или менее привычной форме.

Запись данных

Следующая программа демонстрирует запись символа, целого числа, числа типа

double и двух объектов типа string в дисковый файл. Вывод на экран не произво-

дится. Приведем листинг программы FORMATO.

 

Листинг 12.2. Программа FORMAT)

// formato.cpp

// Форматированный вывод в файл с использованием <<

#include <fstream>        // для файлового ввода/вывода

#include <iostream>

#include <string>

using namespace std;

 

int main()

{

  char ch = 'x';

  int j = 77;

  double d = 6.02;

  string str1 = "Kafka";  // строки без

  string str2 = "Proust"; // пробелов

 

  ofstream outfile("fdata.txt"); //создать объект ofstream

 

  outfile << ch           // вставить (записать) данные

        << j

        << ' '            // пробелы между числами

        << d

        << str1

        << ' '            // пробелы между строками

        << str2;

  cout << "Файл записан\n";

  return 0;

}

Здесь мы определили объект outfile в качестве компонента класса ofstream.

В то же время мы инициализировали его файлом FDATA.TXT. Инициализация

резервирует для дискового файла с данным именем различные ресурсы и полу-

чает доступ (или открывает файл) к нему. Если файл не существует, он созда-

ется. Если файл уже существует, он переписывается — новые данные в нем

заменяют старые. Объект outfile ведет себя подобно cout из предыдущих про-

грамм, поэтому можно использовать операцию вставки (<<) для вывода пере-

менных любого из стандартных типов в файл. Это так замечательно работает

потому, что оператор вставки перегружен в классе ostream, который является

родительским для ofstream.

Когда программа завершается, объект outfile вызывает свой деструктор, кото-

рый закрывает файл, так что нам не приходится делать это явным образом.

Есть несколько потенциальных проблем с форматированным выводом в дис-

ковые файлы. Во-первых, надо разделять числа (77 и 6,02, например) нечисло-

выми символами. Поскольку они хранятся в виде последовательности симво-

лов, а не в виде полей фиксированной длины, это единственный шанс узнать

при извлечении, где кончается одно и начинается другое число. Во-вторых, меж-

ду строками должны быть разделители — по тем же причинам. Это подразуме-

вает, что внутри строки не может быть пробелов. В этом примере для разделе-

ния данных мы использовали пробел в обоих случаях. Радует то, что символы

не нуждаются в разделителях, хотя они и являются данными фиксированной

длины.

 

Посмотреть на результаты работы программы FORMATO можно, открыв файл

FDATA.TXT с помощью программы WORDPAD или команды DOS TYPE.

Чтение данных

Прочитать файл, созданный программой FORMATO, можно с использованием объ-

екта типа ifstream, инициализированного именем файла. Файл автоматически откры-

вается при создании объекта. Затем данные из него можно считать с помощью

оператора извлечения (>>).

Приведем листинг программы FORMATI, которая считывает данные из файла

FDATA.TXT.

Листинг 12.3. Программа FORMATI

// formati.cpp

// форматированное чтение из файла с помощью >>

#include <fstream>              // для файлового ввода/вывода

#include <iostream>

#include <string>

using namespace std;

 

int main()

{

  char ch;

  int j;

  double d;

  string str1;

  string str2;

 

  ifstream infile("fdata.txt"); // создать объект ifstream

                                // извлечь (прочесть) из него данные

  infile >> ch >> j >> d >> str1 >> str2;

 

  cout << ch << endl            // вывести данные

      << j << endl

      << d << endl

      << str1 << endl

      << str2 << endl;

  return 0;

}

 

Объект типа ifstream, который мы назвали infile, действует примерно так же, как

cin в предыдущих программах. Если мы корректно вставляли данные в файл, то

извлечь их не составит никаких проблем. Мы просто сохраняем их в соответст-

вующих переменных и выводим на экран. Результаты работы программы:

 

  х

77

6.02

 Kafka

 Proust

Разумеется, числа приводятся обратно к своему двоичному представлению,

чтобы с ними можно было работать в программе. Так, 77 сохраняется в пере-

менной j типа int, это уже теперь не две семерки символьного типа. 6,02 сохра-

няется в переменной типа double.

 

 

19