Пример 3.2.

Контрольные вопросы и задания.

1. Какие операторы вводят информацию в память компьютера?

2. Каким образом можно ввести информацию при помощи форматирования?

3. Какие существуют виды условного оператора и чем они отличаются?

4. Чем условный оператор принципиально отличается от условной операции?

5. Назовите три вида оператора цикла. Чем они принципиально отличаются между собой?

6. Какое значение возвращает функция floor (x)?

7. Для чего нужен сложный оператор {…} в условном операторе?

8. Для чего используют блок {…} в командах цикла? Может ли тело цикла forне выполняться ни разу? При каком условии?

 

 

лекция 3

 

программирование задач с использованием массивов. указатели.

 

При работе с массивами необходимо обратить внимание на их сохранение, ввод и вывод элементов. При программировании обязательно нужно использовать указатели. Указатель – особый тип данных, предназначенный для сохранения адреса в памяти. Если к указателю массива mas, например, прибавить значение 3, это приведет к получению нового указателя на четвертый (!) по порядку элемент массива. При этом переход выполняется в соответствии к типу массива.

Тесную связь с указателями имеет определенный в языке С++ тип данных – массив, ала вектор. Массив – это структурированный тип данных, который представляет собой пронумерованные элементы одинакового типа. Обозначением массива при описании является наличие парных скобок - [ ]. Элементы массива нумеруются, начиная с 0.

Например:

int mas1[21]; char mas2[67];

 

где объявлены вектор mas1, который содержит 21 элемент типа int и вектор mas2, которй содержит 67 элементов типа char.

В С++ есть два способа доступа к элементам вектора (массива): с использование механизма указателя и классический – с помощью индекса.

Использование механизма указателя основано на использовании факту, что имя вектора (массива) является указателем – константой, которая равна адресу начала вектора (массива) – первого байта первого элемента вектора (массива) (mas1==&mas1[0]). В результате этого используя операцию разименования «*» можно обеспечить доступ к любому элементу вектора (массива). Так эквивалентными будут обращения к i-му элементу вектора (массива) с использованием индекса - mas1[i] и выражения *(mas1+i), так как (mas1+i)==& mas1[i].

Многомерные массивы в С++ представляются в виде векторов указателей на векторы – многомерные вектора.

Багатовимірні масиви в С++ представляються у виді векторів покажчиків на вектори - багатовимірні вектора.

Использование механизма указателей для доступа к некоторому і,j,k-му элементу трехмерного вектора (массива) может быть таким:

b[і][j][k]= = *(b[і][j]+k)= =*(*(b[і]+j)+k)= =*(*(*(b+і)+j)+k) .

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

В современном программировании часто используют динамические массивы, которые хранятся в динамической памяти, которая используется по мере необходимости. Например, одномерный динамический массив создается и удаляется операторами

int n=10;

float *md;

md=new float[n]; // создание

…// обработка

delete [] md; // удаление

Массивы указателей применяют при использовании функция, а также в ситуациях, когда необходимо выполнить какие-либо действия, не изменяя входных данных. Элементами таких массивов являются адреса данных.

Фрагмент программы сортирования массива через массив указателей на его элементы имеет вид

int ma[n], *mp[n]; // описание массива данных и массива указателей

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

mp[i]=&ma[i]; //присвоение адресов

for(i=0; i<n-1; i++) // сортировка указателей

for(j=0; j<n-i-1; j++)

if(*mp[j]>*mp[j+1])

{int *p= mp[j]; mp[j]= mp[j+1]; mp[j+1]=p;}

 

Пример 3.1.

Отсортировать массив mas действительных чисел размером 10 элементов по убыванию.

#include <iostream.h>

#include <сonio.h>

void main()

{ const n=10;

int i, j;

float mas [n], rab;

cout<<"Vvеdі 10 elem \n";

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

cin>>mas[i];// вариант cin>>*(mas+i);

cout<< " Isxodnik\n";

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

cout<<mas[i]; //cout<<*(mas+i)<<" ";

cout<<"\n"; //cout<<endl;

//Сортировка по убыванию

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

for (j=0;j<n-i-1;j++)

if(mas[j]<mas[j+1]) //if(*(mas+j) <*(mas+j+1))

{ rab= mas[j]; //{ rab=*(mas+j);

mas[j] =mas[j+1]; //*(mas+j)=*(mas+j+1);

mas[j+1]=rab;} //*(mas+j+1)=rab; }

// Вывод результата

cout<< " Otsort massiv\n"<<"\n";

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

cout<< mas[i]<<” ”; // cout<<*(mas+i)<<" ";

getch(); //задержка экрана

}

 

В многомерном массиве matrразмером 5*6найти сумму элементов каждой строки. Полученный массив отсортировать по возрастанию.

#include <iostream.h>

#include <conio.h>

void main()

{int i,j,sum,stk;

int matr[5][6], mas[5];

cout<<"Input matr\n";

// Ввод массива

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

for(j=0; j<6; j++) cin>> *(*(matr+i)+j);

// Найти сумму элементов каждой строки

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

{sum=0;

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

sum+=*(*(matr+i)+j); *(mas+i)=sum;}

cout<< "Result mas\n";

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

cout<< *(mas+i)<<" "; cout<<endl;

// Сортировка вестора (массива) mas по возрастанию

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

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

if (*(mas+j)> *(mas+j+1))

{stk=*(mas+j); *(mas+j)= *(mas+j+1); *(mas+j+1)=stk;}

// Вывод отсортированного массива

cout<< "Result otsortirov mas\n";

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

cout<< *(mas+i)<<" "; cout<<endl;

getch(); }

 

Пример 3.3.

Создать динамический масив из n строк и m столбцов (значения n и m ввести с клавиатуры). Найти сумму парных элементов массива.

#include <iostream.h>

void main()

{ int n,m,i;

int **mas;

cout<<"Vveditе kolsch strok (n) i stolbcov (m)"<<endl;

cin>>n>>m;

//создаем динамический массив

mas=new int*[n]; //создаем массив указателей

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

mas[i]=new int[m];

cout<<"Vvedit elementi masiva"<<endl;

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

for(int j=0;j<m;j++) cin>>mas[i][j];

for(i=0;i<n;i++,cout<<endl)

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

cout<<mas[i][j]<<"\t";

int sum(0);

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

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

if(mas[i][j]%2==0) sum+=mas[i][j];

cout<<" sum== "<<sum<<endl;

// освобождаем память

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

delete[]mas[i];//освобождаем строки

delete []mas; //освобождаем массив указателей

cin>>i;

}

 

3.3. Контрольные вопросы и задания.

1. Как понимать выражение *( c+i ), где с – имя указателя?

2. Какие преимущества имеет использование указателей в программах?

3. Как в языке С++ представляют многомерные массивы?

4. Объясните выражение *(*(matr+i)+j).

5. Что такое разименование в языке С++?

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

7. Напишите программу сортирования массива по правилу возрастания с использованием указателей.

8. Как задать изменяющийся размер массиву?

9. Что такое динамические массивы?

10. Объясните использование массивов указателей.

 

ЛЕКЦИЯ 4

 

СТРОКИ. ОБРАБОТКА ДАННЫХ СИМВОЛЬНОГО ТИПА

 

4.1. Работа с данными символьного типа.

 

В языке С++ существует несколько возможностей работы с символьными данными. Классическая работа сводится к использованию массивов символов. При этом существует возможность обработки каждого символа и разработки эффективных алгоритмов.

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

Для того, чтобы воспользоваться стандартними функциями С++ для работы со строками, нужно в программу включить директиву #include <string.h>. Основные функции этой библиотеки приведены ниже. В заголовках функции приведены типы параметров и порядок вызова.

 

— char *strcat (char*_dest, const char*_src); — функция реализует соединение строки dest со строкой src. Функция возвращает указатель на начало полученной строки (dest). Промежуточный символ ‘\0’ строки dest гасится.

— char *strncat (char*_dest, const char*_src, size_t_maxlen); — функция присоединяет maxlen символов из строки, на которую указывает src, до строки, на которую указывает dest. Строка dest должна содержать не меньше maxlen свободных байтов. Если maxlen больше строки src, выполняется простая конкатенация.

— char*strchr (const char*_, int_c); — функция возвращает указатель на позицию первого вхождения символа “c” в строку, на которую указывает s. В строку включается и символ ‘\0’.

— int strcmp (const char*_s1, const char*_s2); — функция выполняет сравнение двух строк, на начало которых указывают s1 и s2. Функция принимает значение меньше нуля, если s1<s2; равное нулю, если s1==s2; больше нуля, если s1>s2.

int strnсmp (const char*_s1, const char*_s2, size_t_maxlen); — функция аналогична функции strcmp () и отличается тем, что выполняется сравнение первых maxlen байтов.

int stricmp (const char *_s1, const char *_s2); — функция выполняет сравнение двух строк, на что указывают s1 и s2. Перед сравнением символы превращаются в маленькие. Функция принимает значение больше нуля, если s1>s2; равное нулю, если s1==s2; меньше нуля, если s1<s2.

int strlen (const char*_s); — функция возвращает длину строки в байтах, на которую указывает s. Нуль-терминатор не учитывается.

char*stpcpy (char *_dest, const char *_src); —функция копирует строку, на которую указывает src, в другое место памяти, на которое указывает dest. Функция возвращает указатель на начало строки, которая копировалась в dest.

char*strncpy (char*_dest, const char*_src, size_t_maxlen); —функция копирует maxlen байт из строки, на которую указывает src, в другое место в памяти, на которое указывает dest. Нуль-терминатор тоже копируется. Если maxlen меньше длины строки src, к строке src не присоединяется символ “\0”. А если больше, то строка src переносится полностью, а символы, которые остались, заполняются символом “\0”. Функция возвращает указатель dest.

char *strlwr (char *_s); —функция превращает все символы строки, на начало которой указывает s, в маленькие буквы. Функция возвращает указатель на начало этой строки.

char *strups (char *_s); —функция превращает все символы строки, на начало которой указывает s, в большие буквы. Функция возвращает указатель на полученную строку.

char *strset (char *_s, int_ch); — функция заполняет строку, на начало которой указывает s, символом ch. Функция возвращает указатель на полученную строку.

 

Пример 4.1

Подсчитать количество слов в строке, учитывая то, что пропусков между словами может быть сколько угодно.

 

#include <iostream.h>

#include <conio.h>

void main()

{ char *s=”Repetitio est mater studiorum ”;

int i=1, col=0;

while (s[i]!=’\0’)

{if (s[i]==’ ’) { col++;

while (s[i]==’ ’)

i++;

}

else i++;

}

cout<<”\n Kolichestvo slov=”<<col<<’\n’;

}

 

Пример 4.2

В предложении найти слово с максимальным количеством букв.

 

#include <iostream.h>

#include <string.h>

#include <stdio.h>

void main()

{char tex1[]=" s1 s2max, slovo kolichchch, bukv!"; // предложение

char *p1,*pmax;

char del[]=" ,!."; // строка символов-разделитель между словами

int dl,dlmax;

cout<<" NACHALO ! ETO VASHA STROKA: "<<tex1<<endl;

p1=strtok(tex1,del); // выделение начального слова

pmax=p1;

dlmax=strlen(p1);

while (p1!=NULL)

{ dl=strlen(p1);

if (dl>dlmax)

{dlmax=dl; pmax=p1;}

p1=strtok(NULL,del); // перемещение указателя к следующему слову,

// начиная с указателя NULL

}

cout <<" max_dlina = "<<dlmax<<" mslovo= "<<pmax<<endl;

}

 

4.4 Контрольные вопросы и задания.

1. Что такое строка символов в языке С++?

2. Какие преимущества имеет работа с массивами символов?

3. Какие преимущества имеет работа со строками символов? Как она реализуется?

4. Разобраться с техникой ввода-вывода строки в С++.

5. Когда можно не описывать длину строки?

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

7. Для чего используется функция strtok?

8. Что делает оператор p1=strtok(NULL,del); ?

 

5 СТРУКТУРЫ

Структура – это упорядоченная совокупность произвольных типов данных, которые объединены в одной области памяти. Тип структуры вводится описанием следующего вида:

struct [ім’я_структури]

{тип_1 ім’я_поля_1;

тип_2 ім’я_поля_2;...;

тип_n ім’я_поля_n;};

 

где имя структуры – имя структуры шаблона, который удовлетворяет правилам задания идентификаторов языка С++;

тип_1, тип_2, ... , тип_n – какие-либо назначенные типы;

имя_поля_1, ... , имя_поля_n – идентификаторы полей, которые удовлетворяют правилам задания идентификаторов.

Описание структуры представляет собой задание нового типа «имя стуктуры» ы не приводит к выделению памяти, а только дает информацию компилятору о типах и количестве полей. Эта информация используется при описании структурированных переменных для резервирования необходимого места в памяти и организации доступа к необходимым полям структурной переменной.

Доступ к полям структуры можно обеспечить двумя способами: используя оператор разименования поля (символ „.”):

имя _структурной_переменной. имя_поля;

или используя оператор указателя на структуру (символы „->”):

указатель_на_структуру-> имя_поля;

Наиболее приоритетным в современном программировании является использование указателей.

Допускается использование массивов структур, структур внутри структур и т.д. Главное при этом – чтобы программист не использовал излишней памяти компьютера и контролировал связь данных внутри созданных структур.

 

Пример 5.1.

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

#include<iostream.h>

#include<conio.h>

const int n=2;

struct Poisk { char name[20];

int year;

int power; };

void main ()

{

Poisk car[n], *point=&car[0];

int i,yy,pp;

bool flag=false;

// введення інформації

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

{

cout << "\nVvedi nazvy avto:";

cin >> point-> name; // або cin >> (*point).name;

cou t<< "\nVvedi rik vipusku:";

cin >> point->year; // або cin >> (*point). year;

cout << "\nVvedi potuznist':";

cin >> point->power; // cin >> (*point). power;

}

point-= n; // повернення покажчика на початок масиву

//Рядок запиту: рік випуску і потужність

cout << "\nVvedit rik vipusku:"; cin >> yy;

cout << "\nVvedi poshukovu potuznist':"; cin >> pp;

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

if((point->year== yy) && (point->power == pp))

{ cout <<"the name of car is\n"<< point->name <<"\n";

flag=true; /* автомобіль знайдено*/

}

if(!flag)

cout<<"Avto ne znajdene\n ";

getch() ;

}

 

5.2. Контрольные вопросы и задания

 

1. С какой целью используется тип данных «структура»?

2. Какие преимущества и недостатки имеет использование структур?

3. Какие типы полей может содержать структура?

4. Как можно обратиться к элементам структуры?

5. Назовите способы описание переменных структурного типа.

6. Можно ли использовать структуру внутри другой структуры?

7. Когда используют массивы структур?

8. Как в приведенном примере программы понимать выражение point->year ?

9. Возможно ли реализовать пример 5.1 без использования массива?

 

6 ФУНКЦИИ

 

Одним из основных элементов программы на языке считается функция. Функция предназначена для создания программных проектов разной степени сложности. Функции, которые предназначены для реализации сложных задач, могут в свою очередь содержать обращения к другим функциям, предназначенным для решения менее сложных задач. Реализация любого проекта в языке С++ допускает функциональную декомпозиция, когда функции более высокого уровня обеспечивают данными и воспринимают результаты функций более низкого уровня.

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

Синтаксис С++ предусматривает, чтобы функция была либо определена, либо объявлена до ее вызова. Объявление функции (задание прототипа функции) содержит имя функции; тип результата, который возвращается; список формальных параметров и их типа, или указание только типов формальных параметров.

В языке С++ определено несколько способов передачи параметров функции и получения результатов вычисления функции. Существует четыре базовых способа передачи параметров: вызов функции с передачей значений; вызов функции с передачей адресов переменных; вызов функций с использованием механизма отправки или передачи параметров; с помощью глобальных параметров. Но не каждый из этих способов обеспечивает возвращение измененных параметров в основную функцию.

Имя функции может быть параметром для другой функции. Можно организовать также встроенную функцию по схеме

inline void myPrint(void) { cout << " Text" << endl; } ,

что значительно сокращает время выполнения программы. Язык С++ допускает перегрузку функций – вызов функций с одинаковым именем, но с разными типами фактических параметров. Для этого используется отдельный прототип и описание каждого списка параметров.

 

Пример 6.1.

Создать функция сортировки в одномерном массиве отрицательных элементов на своих местах.

#include <iostream.h>

const int n=5;

int i, mas[n];

int s=0; int *x;

void SortArr(int *x, int n)

{ int i,j,xmin,imin;

for(j=0;j<n-1;j++)

{

if (*(x+j)<0)

xmin=*(x+j);

for(i=j+1;i<n;i++)

if ((*(x+i)<xmin) || (*(x+i)<0))

{xmin=*(x+i); imin=i;}

*(x+imin)=*(x+j); *(x+j)=xmin;

}

}

// Главная функция

int main()

{ x=&mas[0];

cout<<”\n input 5 members of massiv \n”;

for (i=0;i<n;i++;x++) cin>>*x;

cout<<”Your members:\n”;

for(i=0;i<n;i++) cout <<*(mas+i)<<’ ‘;

cout <<”\n”;

SortArr (mas,n);

cout<<” Result:massiv”<<”\n”;

for(i=0;i<n;i++) cout <<*(mas+i)<<’ ‘;

cout <<”\n”;

getch() ;

return(0);

}

 

6.2 Контрольные вопросы и задания

 

1. Для чего нужен прототип функций?

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

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

4. Использование функция-указателей.

5. организация работы с массивами в функциях.

6. Чем использование ссылок отличается от указателей как параметров?

7. Что такое локальные и глобальные переменные?

8. Может ли функция быть параметром другой функции?

 

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

Enter 1 element

Enter 2 element

Enter 3 element

Enter 4 element

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

5 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)

Авдеев 34-67-89

Бобров 34-56-89

Котов 12-13-14

Попов 45-67-13

Ясин 34-44-54

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

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

Enter name

Попов