Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Мои лекции по С++.doc
Скачиваний:
5
Добавлен:
14.04.2019
Размер:
340 Кб
Скачать

7 Работа с файлами

Во время работы на компьютере часто возникает необходимость использовать данные, которые записаны на внешних носителях информации (например, дисках) и оформлены в виде файлов данных. Файлы представляют собой последовательность байтов. Их компонентами могут быть любые данные (числа, символы, строки, массивы, структуры и др.). Использование файлов данных в программе предусматривает выполнение таких операций:

- создание потока для обмена данными между файлом и памятью;

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

- запись данных в файл или чтение их из файла;

- закрытие файла.

Для реализации этих операций существуют специальные классы, которые содержат конструкторы создания необходимых потоков:

ifstream – для создания потока чтения данных;

ofstream – для создания записи данных в файл;

fstream – используется как для записи данных так и для их чтения.

Конструкторы — это специальные функции, которые создают объекты из соответствующих классов. Конструкторы с параметрами одновременно создают соответствующий поток, связывают его с файлом на диске и открывают файл для работы. Конструкторы потоков имеют такие формы записи:

ofstream ів (“ім “,ios::out); или ofstream ів (“ім“);

ifstream ів(“ім“,ios::in); или ifstream (“ім“);

fstream ів (“ім“, ios::in | ios::out); ,

где ів — имя потока, который создается для работы с файлом;

ім – константа, или переменная типа char[], значением которой есть имя файла на диске.

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

ofstream fout(“ myfile.dat”, ios::out);

Эта запись создает поток с именем “fout”, связывает его с файлом на диске, который имеет имя “myfile.dat” и открывает этот файл для записи данных. Файл “myfile.dat” будет создан в том каталоге, что и программа. Если надо создать файл в другом месте, то при записи его имени надо указать путь, например, “a:\\pvp\\myfile.dat”. Теперь этот файл будет записан на диске “а:” в папке “pvp”. Обратите внимание на то, что при записи пути нужно использовать двойные косые черточки. Если для работы с файлами использовать конструкторы без параметров в виде

ofstream ip;

Ifstream ip;

fstream ip; ,

где ip – имя соответствующего потока, то для связывания потока с именем файла на диске и открытия его для работы нужно дополнительно использовать функцию – член вида:

ip.open(“ім“ , ios:: режим | ios::режим);

Например, открытие файла для записи в него данных можно написать:

ofstream fout;

fout.open(“a:\\pvp\\myfile.dat”,ios::out);

Рассмотрим некоторые примеры работы с файлами.

Пример 7.1 Создать файл на диске и записать в него массив чисел. Затем прочитать этот файл и вывести его компоненты на экран. Программа имеет вид:

#include<iostream.h>

#include<fstream.h>

int main()

{ int i, mas[5];

ofstream fout(“massiv.dat”); //создание потока fout и открытие файла.

іf (!fout){ cout<<”Cannot open file\n”; return 1;}

for(i=0;i<5;i++)

{ cout<<” Enter “<<i<<” element\n”;

cin>>mas[i]; //ввод элементов массива с клавиатуры

fout<<mas[i]<<’ ’; } //взвод элемента в файл.

fout.close();

//чтение компонента файла в память компьютера

//и вывод на экран

ifstream fin(“massiv.dat”); //создание потока fin для чтения файла

if (!fin) { cout<<” Cannot open file fo reading\n”; return 1;}

cout<<”REZULTAT\n”;

for(i=0;i<5;i++)

{ fin>>mas[i]; //чтение очередного элемента массива с диска

cout<<”mas[“<<i<<”]=”<<mas[i]<<” “; } // взвод на экран

cout<< “\nFile reading\n”;

fin.close();

cin>>i;

return 0;}

Результат выполнения программы:

Enter 0 element

15

Enter 1 element

20

Enter 2 element

125

Enter 3 element

94

Enter 4 element

5

REZULTAT

mas[0]=15 mas[1]=20 mas[2]=125 mas[3]=94 mas[4]=5

File reading.

Пример 7.2. Запишем в файл матрицу размерностью 2х4 отдельными строками.

#include<iostream.h>

#include<fstream.h>

void main()

{ int matr[2][4], matr1[2][4];

ofstream out("filemat",ios::out); //открытие файла

for(i=0;i<2;i++)

for(j=0;j<4;j++)

{cin>> matr [i][j];

out<<matr[i][j]<<" ";}

out.close();

//читання з файлу .

ifstreram in("filemat",ios::in); //открытие файла для чтения

for(i=0;i<2;i++)

for(j=0;j<4;j++)

in>>matr1[i][j];

in.close();

// вывод матрицы на экран

cout<< “\nMatrix matr1\n”;

for(i=0;i<2;i++)

{cout<<endl;

for(j=0;j<4;j++)

cout<<matr1[i][j]<<” “;}

cin>>j;

}

Результат работы программы:

Matrix matr1

  1. 7 10 8

15 3 12 10

Пример 7.3. Записать в файл 5 фамилий, затем прочитать их и вывести на экран.

#include<iostream.h>

#include<fstream.h>

#include<conio.h>

int main()

{ char st[5][15]; int i;

// запись в файл

ofstream fout("st_file.dat");

if(!fout) {cout<<"Cannot open file\n"; return 1;}

for(i=0;i<5;i++)

{cout<<" Vvedite "<<(i+1)<<" famil\n";

cin.getline(st[i],15); //ввод очередной фамилиис клавиатуры

fout<<st[i]<<" ";} //запияь очередной фамилии в файл

fout.close();

// чиение из файла и вывод наэкран

cout<<"\nReading file\n\n";

ifstream fin("st_file.dat");

if(!fin) {cout<<"Cannot open file.dat\n"; return 1;}

for(i=0;i<5;i++)

{fin.getline(st[i],15);

cout<<st[i];}

fin.close();

getch();

return 0;

}

Результат работы программы:

Vvedite 1 famil

Avdeev N.M.

Vvedite 2 famil

Bobrov G.K.

Vvedite 3 famil

Volkov U.L.

Vvedite 4 famil

Popov T.K.

Vvedite 5 famil

Jasin H.D.

Reading file

Avdeev N.M. Bobrov G.K. Volkov U.L. Popov T.K. Jasin H.D.

В предыдущих программах запись данных в файл и их чтение из файла осуществлялось последовательно (поэлементно). Но записать или прочитать несколько данных (например, массив чисел) можно одной операцией.

Для этого используют функции – члени соответствующих классов, которые имеют вид:

ip.write((char*)&p,sizeof(p)); — при записи данных в файл,

ip.read((char*)&p,sizeof(p)); — при чтении данных из файла ,

здесь ір — имя потока ввода или вывода; р –— переменная любого типа.

Если эта переменная имеет тип char[], то операция ее приведения не нужна. Рассмотрим пример использования этих функций.

Пример 7.4 Записать в файл массив mas[] одной операцией, затем прочитать этот файл тоже одной операцией в массив mas1[] и вывести этот массив на экран.

#include<iostream.h>

#include<fstream.h>

#include<conio.h>

const int n=5;

int main()

{int i,mas1[n],mas[n]={10,20,30,40,51};

ofstream fout("file_digits.dat", ios::binary); // открытие файла для записи

if(!fout) {cout<<"Cannot open file\n"; return 1;}

fout.write((char*)&mas,sizeof(mas)); //запись массива в файл

fout.close();

ifstream fin("file_digits.dat", ios::binary); // открытие файла для чтения данных

if(!fin) {cout<<"Cannot open file for reading\n"; return 1;}

fin.read((char*)&mas1,sizeof(mas1)); // чтение из файла массива

cout<<"file reading\n";

for(i=0;i<n;i++)

cout<<mas1[i]<<' '; .

cout<<endl;

fin.close();

getch();

return 0;

}

file reading

10 20 30 40 51

Следует отметить, что запись данных в файл и их чтение чаще осуществляется отдельно в разных программах.

Рассмотрим пример, где сначала будет создан файл, в котором запишем список фамилий и их телефоны (данные типа структура). Затем в другой программе будем по запросу выводить на экран весь список или только те фамилии и телефоны, которые нам необходимы.

Пример 7.5 Программа записи структуры в файл.

#include<iostream.h>

#include<fstream.h>

#include<string.h>

struct telefon

{ char fio[15];

char tel[10];};

void main()

{ int i;

telefon spis[5];

ofstream out("struct.dat", ios::binary);

if(!out)cout<<"Cannot open file\n";

for(i=1;i<=5;i++)

{ cout<<"Enter "<<i<<"fio and telefon\n";

cin.getline(spis[i].fio,15); // ввод фамилий с клавиатуры

cin.getline(spis[i].tel,10); // ввод телефона с клавиатуры

// запись фамилии и телефона в файл.

out.write((char*)&spis[i], sizeof(spis[i] ) );

}

out.close();

}

Результат работы программы:

Enter 1 fio and telefon

Авдеев

34-67-89

Enter 2 fio and telefon

Бобров

34-56-89

Enter 3 fio and telefon

Котов

12-13-14

Enter 4 fio and telefon

Ясин

34-44-54

Enter 5 fio and telefon

Пример 7.6 Программа чтения файла, созданного предыдущей программой.

#include<iostream.h>

#include<fstream.h>

#include<string.h>

struct telefon

{ char fio[15];

char tel[10];};

main()

{ int i,p; char name[15]; bool t;

telefon spis;

ifstream in("struct2.dat", ios::binary); //открытие файла, созданного раньше

if(!in) cout<<"\nCannot open file fo reading\n";

// ввод режима работы с файлом

cout<<"Who make: reading list(1) or name(2)\n";

cin>>p; /

if(p==1) // обработка первого режима

{while (in.read(spis.fio,15)) // чтение даннях из файла “struct2.dat”

{in.read(spis.tel,10);

cout<<spis.fio<<' '<<spis.tel<<endl; }

} // вывод данных на экран

if(p==2) // обработка второго режима

{ t=true;

cout<<"Enter name\n";

cin>>name; // ввод фамилии

in.seekg(0); // к началу файла

// цикл чтения данных из файла

while (in.read(spis.fio,15))

{ in.read(spis.tel,10);

if(spis.fio==name)

{cout<<spis.fio<<' '<<spis.tel<<"\n";

t=false;}}

in.close();

if(t)cout<<"Name "<<name<<" it is not\n";}

cin>>i;

}

Результат реализации программы при первом режиме ее работы, когда нежно вывести все данные из файла:

Who make: reading list(1) or name(2)

1

Авдеев 34-67-89

Бобров 34-56-89

Котов 12-13-14

Попов 45-67-13

Ясин 34-44-54

Результат работы программы при втором режиме работы, когда нужно вывести заданную фамилию и телефон, такой:

Who make: reading list(1) or name(2)

2

Enter name

Попов

Попов 45-67-13

Функции write() и read() удобно использовать при организации прямого доступа к данным в файле. Но для этого необходимы также функции – члены, которые позволяют перемещать указатель потока в любое место файла. Эти функции имеют вид:

ip.seekp(n,dir);

ip.seekg(n,dir); .

Первая из них используется при записи данных в файл, а вторая – при их чтении.

Здесь n – параметр, который указывает количество байтов, на которое необходимо переместить указатель потока;

dir – направление перемещения указателя (необязательный параметр). Он может принимать одно из значений:

ios::beg — от начала файла;

ios::cur — от текущей позиции;

ios::endот конца файла.

Если этот параметр не записан, перемещение указателя осуществляется с начала файла.

Рассмотрим программу, в которой используются методы прямого доступа.

Пример 7.7. Запишем в файл числовую матрицу размерностью 3х5, затем, пользуясь средствами прямого доступа, прочитаем из файла сначала вторую строку, а затем первую.

#include<iostream.h>

#include<fstream.h>

#include<iomanip.h>

const int n=3,m=5;

void main()

{ int i,j,mas[m];

char fname[]="matr.dat";

ofstream fout(fname,ios::binary);

if(!fout)cout<<"Cannot open file\n";

for(i=0;i<n;i++)

{ cout<<"Enter "<<i<<"stroku\n";

for(j=0;j<m;j++)

cin>>mas[j];

fout.write((char*)&mas,sizeof(mas)); }

fout.close();

ifstream fin(fname,ios::binary);

if(!fin)cout<<"Cannot open file for reading\n";

fin.seekg(1*sizeof(mas));

cout<<"Vivod 2 i 1 strok matrix\n\n";

fin.read((char*)&mas,sizeof(mas));

for (j=0;j<m;j++)

cout<<setw(3)<<mas[j];

cout<<endl;

fin.seekg(0);

fin.read((char*)&mas,sizeof(mas));

for(j=0;j<m;j++)

cout<<setw(3)<<mas[j];

cout<<endl;

fin.close();

cin>>i;

}

Результат работы прогаммы:

Enter 0 stroku

12 3 4 15 0

Enter 1 stroku

5 6 17 8 10

Enter 2 stroku

11 45 9 46 3

Vivod 2 i 1 strok matrix

5 6 17 8 10

  1. 3 4 15 0

7.3 Контрольные вопросы

  1. Чем файл отличается от массива? Каное основное назначение файлов?

  2. Дайте определение файлу и потоку.

  3. Какие операции необходимо выполнить при работе с файлом данных?

  4. Назовите способы создания потоков и открытия файлов.

  5. Какие данные можно записывать в файл?

  6. Какие функции используют при организации прямого доступа к данным в файле?

  7. Какой порядок создания файла?

СПИСОК ЛИТЕРАТУРЫ:

  1. Основи програмування мовою С++: Навчальний посібник/ Є.П. Путятін, В.П. Степанов, В.П. Пчелінов, Т.Г. Долженкова, О.О. Матат. – Харків: ТОВ „Компанія СМІТ”, 2005. — 320 с.

  2. Керниган Б., Ритчи Д. Язык программирования Си: Пер. с англ. —М.: Финансы и статистика, 1992. — 272 с.

  3. Страуструп Б. Язык программирования С++. Часть 1. — Киев: "ДиаСофт", 1993. — 264 с.

  4. Страуструп Б. Язык программирования С++. Часть 2. — Киев: "ДиаСофт", 1993. — 296 с.

  5. Подбельский В.В. Язык Си+: Учеб. пособие. — М.: БИНОМ, 1995. — 400 с.

  6. Глушаков С.В. и др. Язык программирования С++. —Харьков: Фолио, 2002. — 500 с.

  7. Х.М.Дейтел, П.Дж. Дейтел Как программировать на С++.- М.:ЗАО «Издательство БИНОМ», 2000 г. — 1024 с.

  8. Ван Тассел Д. Стиль, разработка, отладка и испытание программ.-M.:Мир,1985.

  9. Проценко В.С. Техніка програмування мовою С.-Навч. Посібник. –К.:Либідь, 1993. — 224с.

  10. Жешке Р. Толковый словарь стандарта языка Си: — С.-Петербург: Питер, 1994. — 221с.

  11. Язык Си. Книга ответов: Пер. с англ. — М.: Финансы и статистика, 1994. — 160 с.

  12. Бондарев В.М. Программирование на С++.- Харьков: «Компания СМИТ», 2004. — 284с