- •11. Инкапсуляция
- •12. Полиморфизм
- •13. Наследование
- •Управление доступом
- •Элементы класса
- •Элементы данных
- •Элементы функции
- •15. Перегрузка функций
- •16. Конструкторы и деструкторы Конструктор
- •Деструктор
- •17. Параметризированные конструкторы
- •18. Дружественные функции
- •19. Inline-функции
- •20. Передача объектов в функции
- •21. Возвращение объектов функциями
- •22. Массивы объектов
- •23. Указатели на объекты
- •24. Указатель this
- •25. Перегрузка операторов
- •26. Ссылки
- •27. Наследование и спецификаторы доступа
- •28. Конструкторы и деструкторы производных классов
- •29. Множественное наследование. Передача параметров в конструктор базового класса
- •30. Указатели и ссылки на производные типы
- •31. Виртуальные функции
- •32. Чисто виртуальные функции и абстрактные типы
- •33. Раннее и позднее связывание
- •35. Создание собственных операторов вставки и извлечения.
- •36. Форматирование ввода-вывода
- •37. Файловый ввод-вывод
- •38. Чтение и запись в текстовые файлы
- •39. Двоичные файлы
- •40. Функции-шаблоны
- •41. Классы-шаблоны
- •42. Использование пространства имён
- •43. Контейнерные классы
- •46. Основы обработки исключений
- •47. Идентификация типа во время исполнения (rtti)
- •49. Виртуальный базовый класс
37. Файловый ввод-вывод
38. Чтение и запись в текстовые файлы
Для выполнения файлового ввода-вывода в программу необходимо включить заголовочный файл fstream и дать команду using namespace std;.
Открытие и закрытие файлов
В С++ файл открывается путём состыковки его с потоком. Имеется три типа потоков: ввода, вывода и ввода-вывода. Для открытия потока ввода необходимо объявить его как объект класса ifstream. Для открытия потока вывода необходимо объявить его как объект класса оfstream. Потоки, которые выполняют как ввод, так и вывод, должны быть объявлены как объекты класса fstream. Например, следующий фрагмент программы создаёт один поток ввода, один поток вывода и один поток, способный выполнять как ввод, так и вывод:
ifstream in;
ofstream out;
fstream both;
После создания потока единственным способом ассоциировать его с файлом является использование функции open(). Эта функция является членом каждого из трёх классов потоков. Она имеет следующий прототип:
void open(const char *filename, int mode, int access=filebuf::openprot);
Здесь filename является именем файла и может включать указание пути. Величина mode определяет, каким способом открывается файл. Mode может принимать одно или более из следующих значений, (определённых в заголовочном файле fstream):
ios::app
ios::ate
ios::binary
ios::in
ios::nocreate
ios::noreplace
ios::out
ios::trunc
Можно комбинировать два и более из этих значений, используя побитовое ИЛИ.
ios::app указывает на то, что выводимые данные будут добавляться в конец файла. Это значение может быть использовано только для файлов, для которых возможен вывод. Использование ios::ate вызывает поиск конца файла в момент открытия файла.
ios::in задаёт возможность ввода из файла, ios::out указывает, что файл предназначен для вывода. Однако создание потока с использованием ifstream задаёт режим ввода, а создание потока с использованием оfstream задаёт режим вывода, и в этих случаях нет необходимости задавать указанные выше величины.
ios::nocreate задаёт такой режим, при котором функция open() может открыть только существующий файл. ios::noreplace не позволяет открыть файл функции open(), если файл уже существует, но не указаны атрибуты ios::ate или ios::app.
ios::trunc обусловливает уничтожение содержимого файла с заданным именем и усечение длины файла до нуля.
ios::binary обусловливает открытие файла для двоичных операций. Это означает, что не будет никаких преобразований символов.
Величина access определяет, каким образом осуществляется доступ к файлу. Обычно эти атрибуты оставляются по умолчанию, что соответствует нормальному файлу.
В следующем фрагменте открывается нормальный файл для вывода
ofstream out;
out.open(“test”, ios::out);
Тем не менее, практически никогда не бывает подобного вызова функции open(), поскольку второй параметр имеет значение по умолчанию. Поэтому предыдущая инструкция будет выглядеть следующим образом:
out.open(“test”);
Для того чтобы открыть поток одновременно для ввода и вывода, необходимо задать обе величины ios::out и ios::in для режима mode, как показано в следующем примере:
fstream mystream;
mystream.open(“test”, ios::in | ios::out);
Если функции open( ) не удаётся открыть поток, то поток останется равным NULL.
Хотя открытие файла с использованием функции open( ) является вполне допустимым, в большинстве случаев так не делается, потому что класс ifstream, ofstream и fstream содержат конструкторы, открывающие файл. Конструкторы имеют те же параметры и значения по умолчанию, что и функция open( ). Поэтому наиболее типичный способ открытия файла выглядит следующим образом:
ifstream mystream(“myfile”);
Можно использовать следующий код для того, чтобы убедится, что файл действительно открыт:
ifstream mystream(“myfile”);
if (!mystream) {
cout << “Cannot open file.\n”;
// обработка ошибки
}
Для того, чтобы закрыть файл, следует использовать функцию-член close( ). Например, чтобы закрыть файл, состыкованный с потоком mystream, используется следующая инструкция:
mystream.close();
Определение конца файла
Для определения момента достижения конца файла можно использовать функцию-член eof(), имеющую следующий прототип:
int eof();
При достижении конца файла она возвращает ненулевое число, в противном случае возвращает ноль.
Для того чтобы писать в текстовые файлы или читать из них, достаточно воспользоваться операциями << и >> для открытого потока. Например, следующая программа записывает целое число, число с плавающей точкой и строку в файл test:
#include <iostream>
#include <fstream>
using namespace std;
int main( )
{
ofstream out("test");
if(!out) {
cout << "Cannot open file.\n";
return 1;
}
out << 10 << " " << 123.23 << "\n";
out << "This is a short text file.\n";
out.close( );
return 0;
}
Следующая программа читает целое число, число с плавающей точкой, символ и строку из файла, созданного предыдущей программой.
#include <iostream>
#include <fstream>
using namespace std;
int main( )
{
char ch;
int i;
float f;
char str[80];
ifstream in(“test”);
if (!in) {
cout << “Cannot open file.\n”;
return 1;
}
in >> i;
in >> f;
in >> ch;
in >> str;
in.close();
return 0;
}