123.50K
Category: programmingprogramming

Файловый ввод-вывод

1.

МИНИСТЕРСТВО НАУКИ И ВЫСШЕГО ОБРАЗОВАНИЯ РОССИЙСКОЙ ФЕДЕРАЦИИ
федеральное государственное бюджетное образовательное учреждение
высшего образования
«Сибирский государственный университет науки и технологий
имени академика М.Ф. Решетнева»
Кафедра Информатики и вычислительной техники
Дисциплина: Программирование (С++)
Лекция «Файловый ввод-вывод»
Читает старший преподаватель
Филимонова Ольга Александровна

2.

Ввод-вывод в языке С++ может быть
осуществлен через функции ввода-вывода
и через потоки в стиле ООП.

3.

Что такое поток?
Поток - абстрактное понятие, относящееся к
любому переносу информации от источника
приемнику.
Потоки логически делятся на 3 вида:
• Входные (из которых информация вводится )
• Выходные (в которые информация выводится)
• Двунаправленные (в которые информация как
вводится, так и выводится)

4.

Потоковый ввод-вывод основан на понятии
класса (пользовательского типа данных)
ios - базовый потоковый класс
istream - класс входных потоков
ostream - класс выходных потоков
iostream - класс двунаправленных потоков
ifstream - класс входных файловых потоков
ofstream - класс выходных файловых потоков
fstream - класс файловых потоков ввода/вывода

5.

Помни!
Иерархия классов создана на базе
наследования.
Классы файловых потоков являются
производными, следовательно, наследуют
все методы, операции, манипуляторы и
прочие средства ввода-вывода,
объявленные в вышестоящих
(родительских) классах.

6.

Для использования файловых потоков
необходимо подключать следующие средства:
#include <iostream>
using namespace std;
#include <fstream>
#include <iomanip>
Для работы с файлами необходимо выполнить следующие
действия:
• Создать поток (то есть объявить объект одного из файловых
классов)
• Связать поток с файлом с помощью метода open()
• Произвести обмен с потоком (то есть осуществить ввод-вывод
данных)
• Закрыть поток (то есть разорвать связь между потоком и
файлом)

7.

Как создать поток?
Необходимо определить, какие действия будут
осуществляться с файлом:
• Ввод информации
• Вывод информации
• Корректировка (изменение существующего) файла
И в соответствии с этим объявить переменную одного из
трёх известных файловых классов (типов):
• ifstream fin;
//ввод из файла (чтение)
• ofstream fout; //вывод в файл (запись)
• fstream f;
//изменение файла

8.

Как связать поток с файлом?
Используется метод (функция) open():
… open(char*file, int mode, int access) ; //объявление функции
где:
file - строка с названием файла с путём или без (если он в
текущем каталоге);
mode - режим открытия файла (то есть с какой целью будем
открывать файл);
access - права доступа к файлу:
0 - свободный доступ (по умолчанию)
1 - файл для чтения
2 - скрытый файл
4 - системный файл
8 - архивный файл

9.

Режимы открытия
• ios:: app - вывод происходит всегда в конец файла
• ios:: ate - указатель потока при открытии позиционируется в конец
файла, в дальнейшем позиционирование можно изменить
• ios:: trunc - при открытии файла содержимое уничтожается
(вывод)
• ios:: _Nocreate - открыть существующий файл; если его нет формируется ошибка
• ios:: _Noreplace - создать новый файл, если файл существует ошибка
• ios:: binary - открыть в двоичном (по умолчанию в текстовом)
режиме
• ios:: in - поток для ввода
• ios:: out - поток для вывода
| - несколько режимов соединяются побитовым «ИЛИ»

10.

Пример 1
Связать поток fin с файлом f1.txt,
расположенном в текущем каталоге. Из
файла будем читать (вводить) информацию:
fin.open (“f1.txt”, ios:: _Nocreate );
if (!fin)
//Проверка успешности обязательна
{
cout << “\n Нет исходного файла \n”;
return -1;
}

11.

Пример 2
Связать поток fout с файлом f2.txt,
расположенном не в текущем каталоге. В
файл пишем (выводим) информацию,
каждый раз его обновляем :
fout.open (“c:\\user\\f2.txt”, ios:: trunc);
if (!fout)
{
cout << “\n Нет файла-результата \n”;
return -1;
}

12.

Пример 3
Имя файла вводим с клавиатуры , свяжем с
ним поток f для изменения файла:
char File[80];
cin>> File;
f.open (File, ios:: in| ios:: out | ios:: binary);
if (!f)
{
cout << “\n Нет файла для изменения \n”;
return -1;
}

13.

Как организовать обмен с
потоками?
Ввод-вывод осуществляется в соответствии с положением указателя потока. При
открытии файла указатель находится в начале файла (по умолчанию, если не было
особых режимов открытия). Указатель потока движется вслед за чтением или
записью автоматически.
Информация обрабатывается ПОРЦИЯМИ:
• Посимвольно, с учётом пробельных символов:
Ввод:
char simv;
fin.get (simv);
Вывод:
fout.put(simv); //Нужны ли разделительные символы при выводе?
• Посимвольно, игнорируя пробельные символы:
Ввод:
fin>>simv;
Вывод:
fout<<simv; //Нужны ли разделительные символы при выводе?

14.


Построчно, включая пробелы:
Ввод
char str[80];
fin.getline(str,80);
Вывод
fout<<str<<endl;
Словами , то есть строки без
пробелов:
Ввод
char slovo [30];
fin>>slovo;
Вывод
fout<<slovo<<‘ ‘;
Числами того или иного типа:
Ввод
double a;
fin>>a;
Вывод
fout<<a; //Как разделяем?
Двоичный ввод-вывод
Ввод
char str[80];
fin.read(str,strlen(str));
Вывод
fout.write(str,strlen(str));

15.

Дополнительные методы
• fin.seekg(-1,ios::cur);
Cмещает указатель потока на один символ, назад,
к началу файла относительно текущей позиции
ios::cur (ios::beg, ios::end)
• long l;
l=fin.tellg();
Определяет местоположения указателя потока в
текущий момент времени относительно начала
файла

16.

Цикл обработки файла
while (чтение порции из файла)
{
//обработка прочитанной порции
}

17.

Методы состояния потоков
• fin.eof() //ненулевое значение-конец файла
• fin.good() //ненулевое значение- нет ошибок
• fin.fail() // ненулевое значение- установлен
• fin.bad() // соответствующий флаг ошибки

18.

Как закрыть поток?
• fin.close();
fout.close();
f.close();

19.

Пример 1. Обработка чисел
//подсчет количества чисел в файле
#include <fstream>
#include <iostream>
using namespace std;
int main(void)
{
ifstream fin;
int kol=0;
int chislo;
fin.open("1.txt", ios::_Nocreate );
if(!fin)
{
cout<<"\n Нет исходного файла";
return -1;
}
while(fin>>chislo)
{
kol++;
}
cout<<"\n Kol = "<<kol<<endl;
fin.close();
}

20.

Обработка символов и строк
При вводе-выводе строк и символов возможно
использовать стандартные функции обработки строк и символов
для дальнейшего преобразования:
strlen()- определяет реальный размер строки
strcpy()- копирует одну строку в другую
strncpy() – копирует n символов одной строки с другую
strcat() – дозапись одной строки в конец другой
strncat() – дозапись n символов одной строки в другую
strstr() – поиск подстроки в другой строке
strcmp() – сравнение на равенство двух строк
strncmp() – сравнение на равенство n символов двух строк
strnicmp() – сравнение n символов без различий регистров
atoi() – преобразование строки в целое число
atof() – преобразование строки в вещественное число
tolower() – преобразование символа к нижнему регистру
toupper() – преобразование символа к верхнему регистру
И пр.

21.

Пример 2
//подсчет количества символов в файле
#include<fstream>
#include<iostream>
using namespace std;
int main (void)
{
char s;
long l=0;
ifstream fin;
fin.open("ff1.txt", ios::_Nocreate);
if(!fin)
{
cout<<"\nНет файла";
return 1;
}
while(fin.get(s))
l++;
cout<<endl<<"kol="<<l<<endl;
fin.close();
return 0;
}

22.

Пример 3
//заполнение файла строками с клавиатуры
#include <fstream>
#include <iostream>
using namespace std;
int main(void)
{
ofstream fout;
char str[80];
fout.open("3.txt", ios::trunc);
if(!fout)
{
cout<<"\n Файла нет";
return -1;
}
while(1)
{
cout<<"Enter text for the file: "<<endl;
cin.getline(str,80);
if(str[0]==0)
break;
fout<<str<<endl;
}
fout.close();
return 0;

23.

Пример 4
//В существующем файле f.txt заменить все цифры на *
#include<fstream>
#include<iostream>
using namespace std;
int main (void)
{
char s;
long l;
fstream f;
f.open("f.txt", ios::in|ios::out|ios::binary|ios::_Nocreate);
if(!f)
{
cout<<"\nНет файла";
return 1;
}

24.

Продолжение примера 4
while(f.get(s))
{
if(s>='0'&&s<='9')
{
f.seekg(-1, ios::cur);
f.put('*');
f.seekg(f.tellg());
}
}
f.close();
cout<<"\ngood!";
return 0;
}

25.

Файлы и функции
При построении функции в качестве параметра
можно передавать:
Имя файла (параметр: char *File)
Ссылку на поток (параметр: ifstream & fin)
В первом случае нет уверенности, что файл нашелся
и удачно читается, поэтому тип функции bool.
Во втором случае поток должен быть объявлен и
инициализирован в вызывающей функции. В
случае успешности – поток передаем в функцию.

26.

//перепишем пример 2 через функцию
#include<fstream>
#include<iostream>
using namespace std;
int Func(ifstream & fin)
{
char s; int l=0;
while(fin.get(s))
l++;
return l;
}
int main (void)
{
long l;
ifstream fin;
fin.open("ff1.txt", ios::_Nocreate);
if(!fin)
{
cout<<"\nНет файла";
return 1;
}
l=Func(fin);
cout<<endl<<"kol="<<l<<endl;
fin.close();
return 0;
}

27.

Спасибо за внимание
English     Русский Rules