Потоковая обработка файлов.
Для работы с файлами используются специальные типы данных, называемые потоками.
Поток ifstream служит для работы с файлами в режиме чтения.
Поток ofstream служит для работы с файлами в режиме записи.
Поток fstream служит для работы с файлами в режиме, как чтения, так и записи.
В программах на C++ при работе с текстовыми файлами в потоковом режиме необходимо подключать библиотеки <iostream> и <fstream>.
С++ поддерживает всю систему ввода/вывода С и добавляет к ней дополнительные возможности, связанные в основном с вводом/выводом объектов. Описание средств для создания потоков в С++ представлено в заголовочном файле <iostream.h>. Когда начинает работать программа на языке С++, открываются потоки, приведенные в табл.5.
Таблица 5. Потоки, определяемые в языке С++.
Имя стандартного файла | Описание |
cin | Стандартный ввод - клавиатура |
cout | Стандартный вывод - экран |
cerr | Стандартная ошибка - экран |
clog | Буферизованная версия cerr - экран |
Основные алгоритмы работы с файлами
Для записи данных в файл нужно выполнить:
1. Описать переменную типа ofstream.
2. Открыть файл для записи с помощью функции open.
3. Вывести информацию в файл с помощью cout.
4. Обязательно закрыть файл.
Для чтения данных из текстового файла нужно выполнить:
1. Описать переменную типа ifstream.
2. Открыть файл для чтения с помощью функции open.
3. Считать информацию из файла с помощью cin при считывании каждой порции данных необходимо проверять, что чтение возможно.
4. Закрыть файл.
Порядок работы с потоками
Описание потоковой переменной
Для того чтобы начать работать с текстовым файлом, необходимо описать переменную типа ofstream.Например, с помощью оператора
ofstream F;будет создана переменная F для записи информации в файл.
Открытие файла
В общем случае оператор открытия файла будет иметь вид:
F.open("file", mode);где F– переменная, описанная в нашем случае как ofstream;
file– полное имя файла на диске;
mode– режим работы с открываемым файлом.
Существуют следующие режимы для открытия файла (см. табл.6).
Таблица 6. Режимы работы с потоком при его открытии
Режимы работы с файлом при открытии | |
Режим | Описание |
ios::in | открыть файл в режиме чтения данных, этот режим является режимом по умолчанию для потоков ifstream |
ios::out | открыть файл в режиме записи данных, этот режим является режимом по умолчанию для потоков ofstream |
ios::app | открыть файл в режиме записи данных в конец файла |
ios::ate | передвинуться в конец уже открытого файла |
ios::trunc | очистить файл, это же происходит в режиме ios::out |
ios::nocreate | не выполнять операцию открытия файла, если он не существует |
ios::noreplace | не открывать существующий файл |
ios::binary | открыть двоичный файл |
Параметр mode может отсутствовать, в этом случае файл открывается в режиме по умолчанию для данного потока:
ios::in– для потоков ifstream,
ios::out– для потоков ofstream.
После удачного открытия файла (в любом режиме) в переменной F будет храниться 1 (true), в противном случае 0 (false). Это позволит проверять корректность операции открытия файла.
Если открытие файла завершилось неудачей, объект, соответствующий потоку, будет возвращать значение 0:
if (!ofs){ cout << "Файл не открыт\n"; }Проверить успешность открытия файла можно также с помощью функции is_open(). Функция возвращает 1, если поток удалось связать с открытым файлом. Например,
if (!ofs.is_open()) cout << "Файл не открыт\n";Открыть файл в режиме записи можно одним из следующих способов:
Первый способ
ofstream F;F.open("abc.txt", ios::out);Второй способ, режим ios::out является режимом по умолчанию для потока ofstream
ofstream F;F.open("abc.txt");Третий способ объединяет описание переменной типа поток и открытие файла в одном операторе.
ofstream F("abc.txt", ios::out);После открытия файла в режиме записи, будет создан пустой файл, в который можно будет записывать информацию. Если необходимо открыть существующий файл (при этом сохранить его содержимое), то в качестве режима следует использовать значение ios::app.
Обработка
После открытия файла в режиме записи, в него можно писать точно так же, как и на экран, только вместо стандартного устройства вывода cout необходимо указать имя открытого для записи файла.
Например, для записи в поток F переменной a, оператор вывода будет иметь вид:
F << a;Для последовательного вывода в поток G переменных b, c и d оператор вывода станет таким:
G << b << c << d;Чтение из файла выполняется корректно до достижения конца файла. Для проверки, достигнут ли конец файла, можно использовать функцию
ios::eof(),которая имеет прототип int eof();.
Данная функция возвращает 0, если конец файла не достигнут, и значение 1 при достижении конца файла.
Закрыттие файла
Открытые на диске файлы после окончания работы с ними рекомендуется закрыть. Оператор закрытия файла будет иметь вид:
F.close;где F– переменная для записи информации в файл.
Пример 1. Работа с файлом в потоковом режиме.
#include "stdafx.h"#include <iostream>using namespace std;#include <fstream>int _tmain(int argc, _TCHAR* argv[]){ int n = 50; char str[20]; // Открываем файл для вывода ofstream ofs("Test.txt"); // Проверка корректности открытия файла if (!ofs) cout << "Файл не открыт.\n"; else { ofs << "Hello!\n" << n; // Закрываем файл ofs.close(); } // Открываем тот же файл для ввода ifstream file("Test.txt"); // Проверка корректности открытия файла if (!file) cout << "Файл не открыт.\n"; else { file >> str >> n; cout << str << "\n" << n; // Закрываем файл file.close(); } system("pause"); return 0;}
При использовании библиотеки классов С++ операции открытия, создания и закрытия, выполняются при создании объектов выходного (входного ) файлового потока.
Пример 2.
#include <iostream.h>
#include <fstream.h> // ofstream
#include <stdlib.h> // содержит функцию exit
int main()
{ char sim;
// создаётся файл, старый стирается
ofstream myfile("d:\oop\myfile.txt",ios::out);
if(!myfile)
{
cerr<<" ошибка открытия myfile.txt"<<endl;
exit(1);
}
for(int i=1;i<10;i++){
cout<<"введите символ"<<endl;
cin>>sim;
myfile.put(sim); }
myfile<<endl;
return 0;
}
Пример 3.
#include <iostream.h>
//#include <fstream.h> // ofstream
#include <fstream.h>
#include <stdlib.h> // содержит функцию exit
int main()
{ char sim;
ifstream myfile("d:\oop\myfile.txt",ios::in);
if(!myfile)
{
cerr<<" ошибка открытия myfile.txt"<<endl;
exit(1);
}
int nsim=0, kolstr=0;
while (myfile.get(sim)){
if (sim==char("\n"))
kolstr++;
else
nsim++;
cout.put(sim); }
cout<<endl<<endl<<"kolstr="<<kolstr<<" "<<"nsim="<<nsim<<endl;
cin>>nsim;
return 0;
}
Пример 4.
#include <iostream.h>
#include <fstream.h> // ofstream
#include <stdlib.h> // содержит функцию exit
int main()
{ char sim;
ofstream myfile("d:\oop\myfile.txt",ios::in); // открывается
// файл для чтения
if(!myfile)
{
cerr<<" ошибка открытия myfile.txt"<<endl;
exit(1);
}
for(int i=1;i<10;i++){........................}
cout<<"введите символ"<<endl;
cin>>sim;
myfile.put(sim); }
myfile<<endl;
return 0;
}
Пример 5.
#include <iostream.h>
#include <fstream.h> // ofstream
#include <stdlib.h> // содержит функцию exit
#define size 40
int main()
{ char sim,*filename;
cout<<"введите имя файла и путь d:\oop\myfile.txt \n";
filename=new char(size);
cin.getline(filename,size);
ofstream myfile(filename,ios::out);
if(!myfile)
{
cerr<<" ошибка открытия myfile.txt"<<endl;
cin>>sim;
exit(1);
}
for(int i=1;i<10;i++){. . . . . . . . . . }
cout<<"введите символ"<<endl;
cin>>sim;
myfile.put(sim); }
myfile<<endl;
delete[]filename;
return 0;
}