Лабораторная работа №17.
Потоки ввода-вывода. Файловые операции
Цель и порядок работы
Цель работы – ознакомиться с возможностями ввода-вывода языка C++, освоить основные операции работы с файлами.
Порядок выполнения работы:
- ознакомиться с описанием лабораторной работы;
- получить задание у преподавателя, согласно своему варианту;
- написать программу и отладить ее на ЭВМ;
- оформить отчет.
Краткая теория
Текстовыми называют файлы, состоящие из любых символов. Они организуются по строкам, каждая из которых заканчивается символом "конец строки". Конец самого файла обозначается символом " конец файла ". При записи информации в текстовый файл, просмотреть который можно с помощью любого текстового редактора, все данные преобразуются к символьному типу и хранятся в символьном виде.
1) Для работы с файлами используются специальные типы данных, называемые потоками. Поток ifstream служит для работы с файлами в режиме чтения.
2) Поток ofstream служит для работы с файлами в режиме записи.
3) Для работы с файлами в режиме как чтения, так и записи служит поток iofstream.
4)
В программах на C++ при работе с текстовыми файлами необходимо подключать библиотеки iostream и fstream.
Для того, чтобы записать данные в текстовый файл, необходимо:
1. Описать переменную типа ofstream.
2. Открыть файл с помощью функции open.
3. Вывести информацию в файл.
4. Закрыть файл.
Для того, чтобы считать данные из текстового файла, необходимо:
1. Описать переменную типа ifstream.
2. Открыть файл с помощью функции open.
3. Считать информацию из файла, при считывании каждой порции данных необходимо проверять достигнут ли конец файла.
|
4. Закрыть файл.
Запись информации в текстовый файл
Для того, чтобы начать работать с текстовым файлом, необходимо описать переменную типа ofstream. Например, с помощью оператора
ofstream F;
будет создана переменная F для записи информации в файл. На следующем этапе файл необходимо открыть для записи. В общем случае оператор открытия потока будет иметь вид:
F.open("file", mode);
Здесь F — переменная, описанная как ofstream, file — имя файла на диске, mode — режим работы с открываемым файлом.
Файл может быть открыт в одном из следующих режимов:
· ios::in — открыть файл в режиме чтения данных, этот режим является режимом по умолчанию для потоков ifstream;
· ios::out — открыть файл в режиме записи данных (при этом информация в существующем файле уничтожается), этот режим является режимом по умолчанию для потоков ofstream;
· ios::app — открыть файл в режиме записи данных в конец файла;
· ios::ate — передвинуться в конец уже открытого файла;
· ios::trunc — очистить файл, это же происходит в режиме ios::out;
· ios::nocreate — не выполнять операцию открытия файла, если он не существует6;
· ios::noreplace — не открывать существующий файл.
Параметр mode может отсутствовать, в этом случае файл открывается в режиме по умолчанию для данного потока.
После удачного открытия файла (в любом режиме) в переменной F будет храниться true, в противном случае false. Это позволит проверять корректность операции открытия файла.
Открыть файл (в качестве примера возьмём файл abc.txt) в режиме записи можно одним из следующих способов:
//Первый способ.
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.
Закрытие файла
В классах файловых потоков имеется функция close(), которая сбрасывает содержимое потока и закрывает ассоциированный с ним файл.
Кроме того, деструктор потока автоматически закрывает файл при уничтожении объекта потока.
При ошибке закрытия файла устанавливается флаг failbit.
Чтение символов и строк
Для чтения одиночных символов, а также строк применяется функция get класса istream. Эта функция перегружена следующим образом:
int get();
istream &get(char &c);
istream &get(char *buf, long len, char t = '\n');
Две первые формы функции предназначены для извлечения из потока одиночного символа. Функция int get() возвращает символ в качестве своего значения. Функция get (char &c) передает символ в параметре и возвращает ссылку на свой поток.
Пример 1. Блок посимвольного копирования файлов
ifstream ifs("infile.dat");
ofstream ofs("outfile.dat");
// put (char) передает в поток
// одиночный символ.
while (ifs & ofs)
ofs.put(ifs.get());
Последняя форма функции get() извлекает из потока последовательность символов. Символы читаются в буфер buf, пока не произойдет одно из следующих событий:
- будет встречен ограничивающий символ t (по умолчанию '\n');
|
- будет встречен конец файла;
- в буфер будет записано len символов, включая завершающий строку 0.
Имеется еще функция getline(), во всем аналогичная этой форме get():
istream &getline(char *buf, long len, char t = '\n');
Разница между этими двумя функциями состоит в том, что getline() извлекает из потока ограничивающий символ, в то время как get() этого не делает. Ни та, ни другая функция не записывает ограничивающий символ в буфер.
Пример 2. Блок чтения строк с помощью get()
#include "stdafx.h"
#include <iostream>
using namespace std;
int main()
{
setlocale(LC_ALL, "Russian");
char name[9], ext[4];
cout << "Введите имя файла: ";
cin.get(name, 9, '.');
cin.ignore (80, '.'); // Удалить все оставшиеся до точки символы
cin.get(ext, 4);
cin.ignore(80, '\n'); // Удалить все, что осталось в строке
cout<< "Имя: "<< name << " Расширение: " << ext << endl;
return 0;
}
Примеры программ
#include <fstream>
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
setlocale(LC_ALL, "rus"); // корректное отображение Кириллицы
char buff[50]; // буфер промежуточного хранения считываемого из файла текста
ifstream fin("cppstudio.doc"); // (ВВЕЛИ НЕ КОРРЕКТНОЕ ИМЯ ФАЙЛА)
if (!fin.is_open()) // если файл не открыт
cout << "Файл не может быть открыт!\n"; // сообщить об этом
else
{
fin >> buff; // считали первое слово из файла
cout << buff << endl; // напечатали это слово
fin.getline(buff, 50); // считали строку из файла
fin.close(); // закрываем файл
cout << buff << endl; // напечатали эту строку
}
system("pause");
return 0;
}
Пример 1. Поиск подстроки
Написать программу, которая определяет, сколько раз встречается в заданном текстовом файле заданная последовательность символов. Длина строки текста не превышает 80 символов, текст не содержит переносов слов, последовательность не содержит пробельных символов.