Файлы. Создание и анализ программы. Поиск подстроки. Алгоритм решения задачи

Страницы работы

Фрагмент текста работы

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

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

Программа

#include <fstream.h>

#include <string.h> 

#include <stdlib.h> 

int main() {

const int l_name = 30,                         l_year =5,                        l_pay = 10,                       l_buf = l_name + l_year + l_pay;

struct Man {                                                   

char name [l_name+1];

int birth_year;

float pay;

};

const int l_dbase = 100;

Man dbase [l_dbase];

char buf[l_buf+1];

ifstream fin (“dbase.txt”, ios::in | ios::nocreate); 

if (!fin) { cout << “Error” << endl;    

return 1;}

int i =0;                                                             

while (fin.getline(buf, l_buf)) {                       

               strncpy  (dbase[i].name, buf, l_name);

              dbase[i].name[l_name] = ‘\0’;

              dbase[i]. birth_year = atoi(&buf [l_name]);                     

 dbase[i]. pay = atof(&buf [l_name+l_year]);                     

               i++;

if (i>= l_dbase) {

cout <<   “Error: l>=l_base” << endl;    

return 1;

}

}

int n_record = i;           

fin.close();                              

ofstream fout (“dbase.txt”); 

if (!fout) { cout << “Error open” << endl;    

return 2;}

for (i=0; i<n_record-1; i++) {

//принимаем за наименьший первый из элементов

int imin=i;

//поиск номера минимального элемента из неупорядоченных

for (int j=i+1; j<n_record; j++)

if (dbase[j].birth_year < dbase[imin].birth_year) imin=j;

//обмен двух элементов массива структур

Man a = dbase[i];  //для структур одного типа определена операция присваивания

dbase[i] = dbase[imin];

dbase[imin] = a; 

}                                                                                                                           

for (i=0; i<n_record; i++) {

fout << dbase[i].name << dbase[i].birth_year << ‘ ‘ << dbase[i].pay << endl;

          }

         fout.close();

cout << “OK”<< endl;

return 0;

}

Создание и анализ программы 5.

Структуры и бинарные файлы

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

Программа

#include <fstream.h>

#include <string.h> 

#include <stdlib.h> 

#include <windows.h>                                                                                  

 #include <iomanip.h>                                                                                  

int main() {

const int l_name = 30;

struct {  char name [l_name+1];                                           

int birth_year;

float pay;

} man;

fstream fin (“dbase.txt”, ios::in | ios::nocreate); 

if (!fin) { cout << “Error” << endl;    

return 1;}

fstream fout (“dbase.bin”, ios::binary| ios::out); 

if (!fout) { cout << “Error open” << endl;    

return 2;}

while (true) {               

fin >>man.name >> man.birth_year >> man.pay; //читаем из файла

 //CharToOem (man.name, man.name);  //при использовании кириллицы

if (fin.eof()) break;

 cout.setf(ios::left);                    //выводим на экран

cout<<setw(30)<<man.name<<setw(5)<<man.birth_year<<setw(10)<<man.pay<< endl;

  fout.write(reinterpret_cast<char *>(&man), sizeof(man)); //записывем в файл

}

fin.close();                              

         fout.close(); //бинарный файл записан

cout << “OK”<< endl;

return 0;

}

Для корректировки бинарного файла выполним программу:

#include <fstream.h>

#include <string.h> 

#include <stdlib.h> 

#include <iomanip.h>                                                                                   

int main() {

const int l_name = 30;

struct {  char name [l_name+1];                                           

int birth_year;

float pay;

} man;

fstream fioun (“dbase.bin”, ios::in | ios::out |  ios::nocreate| ios::binary); 

if (!fioun) { cout << “Error” << endl;    

return 1;}

//вывод содержимого фала на экран

while (!fioun.eof()) {                                                   //пока не конец файла

fioun.read (reinterpret_cast<char *>(&man), sizeof(man));

                  cout.setf(ios::left);                    //выводим на экран

cout<<setw(30)<<man.name<<setw(5)<<man.birth_year                                                                                             <<setw(10)<<man.pay<< endl;

//последняя запись файла выводится 2 раза !!! – плохо реализован цикл

}                             

//текст в рамке можно заменить на нижеследующий  (файл будет выводиться нормально):

while (true)          

{ fioun.read (reinterpret_cast<char *>(&man), sizeof(man));

if (fioun.eof()) break;    //если конец файла

                      cout.setf(ios::left);                    //формат вывода на экран

cout<<setw(30)<<man.name<<setw(5)<<man.birth_year                                                                                               <<setw(10)<<man.pay<< endl;             

                   }  //текст на кириллице выводится правильно, т.к. при записи в файл                                   // была вызвана функция CharToOem (man.name, man.name);

//или еще иначе

fioun.seekg(0, ios::end);  //перемещение текущей позиции чтения в конец файла

int n_record= fioun.tellg()/sizeof(man); // значение текущей позиции чтения                                                                  //и определяем количество записей в файле

fioun.seekg(0, ios::beg);  //устанавливаем текущую позицию чтения в начало файла

for (int i=0; i<n_record; i++) {

                   fioun.read (reinterpret_cast<char *>(&man), sizeof(man));

                   cout.setf(ios::left);                    //выводим на экран

cout<<setw(30)<<man.name<<setw(5)<<man.birth_year                                                                                              <<setw(10)<<man.pay<< endl;

}                                        //последняя запись файла выводится 1 раз !!!

cout << endl << endl;

int pos, n;   

fioun.clear();  //очистка состояния ошибки: после конца файла она была eofbit

fioun.seekg(0, ios::beg);  // для считывания установить указатель файла в начало

while (true) {

cout << “input n  or -1” << endl;

cin >> n;                          //ввод номера сотрудника n

if (n<0 || n> n_record) break;     

pos= (n-1) * sizeof(man);  //вычисление 1-го байта с информацией о сотруднике n

fioun.seekg(pos);     //установить указатель файла на нужный байт

fioun.read (reinterpret_cast<char *>(&man), sizeof(man));  //чтение старой информации

cout.setf(ios::left);                    //выводим на экран

cout<<setw(30)<<man.name<<setw(5)<<man.birth_year<<setw(10)<<man.pay<< endl;

fioun.seekp(pos);    // установить указатель файла на нужный байт

cout << “Input:  man.name – 30;  man.birth_year – 5; man.pay – 10?  “<< endl;

cin >>man.name >> man.birth_year >> man.pay;

         cout.setf(ios::left);                    // выводим на экран

        cout<<setw(30)<<man.name<<setw(5)<<man.birth_year<<setw(10)<<man.pay<< endl;

fioun.write(reinterpret_cast<char *>(&man), sizeof(man));  //запись в файл

}

         fioun.close();

cout << “OK”<< endl;

return 0;

}

Создание и анализ программы 6.

Структуры в динамической памяти и бинарные файлы

Требуется написать программу, которая выводит на экран содержимое бинарного файла, сформированного в задаче 5, упорядочивая фамилии сотрудников по алфавиту.

Программа

#include <fstream.h>

#include <string.h> 

#include <stdlib.h>      //для qsort

#include <iomanip.h>                                                                                   

int compare (const void *man1, const void* man2);

const int l_name = 30;

struct Man{char name [l_name+1];                                    

int birth_year;

float pay;

};

int main() {

fstream fioun (“dbase.bin”, ios::in | ios::out |  ios::nocreate| ios::binary); 

if (!fioun) { cout << “Error” << endl;    

return 1;}

fioun.seekg(0, ios::end);  //перемещение текущей позиции чтения в конец файла

int n_record= fioun.tellg() / sizeof(Man); // значение текущей позиции чтения                                                                  //и определяем количество записей в файле

Man *man = newMan [n_record]; //выделение памяти под массив структур

fioun.seekg(0, ios::beg);  //устанавливаем текущую позицию чтения в начало файла

fioun.read (reinterpret_cast <char *>(man), sizeof(Man)*n_record);

fioun.close();

qsort (man, n_record,  sizeof (Man), compare);  

fioun.seekg(0, ios::beg);  //устанавливаем текущую позицию чтения в начало файла

fioun.clear();

for (int i=0; i<n_record; i++) {

cout.setf(ios::left);                    //выводим на экран

cout<<setw(30)<<man[i].name<<setw(5)<<man[i].birth_year<<setw(10)                                                                                      <<man[i].pay<< endl;

}                                        

cout << endl << endl;

cout << “OK”<< endl;

delete []man ;

return 0;

}

int compare (const  void*man1, const  void* man2)

{return  strcmp ((reinterpret_cast <const Man*>(man1))->name,                                      (reinterpret_cast <const Man*>(man2))->name);

}

Особенности данной программы:

1. Функция readсчитывает весь файл в динамический  массив за одно обращение.

2. Для сортировки массива используется стандартная функция qsort (прототип в заголовочном файлеstdlib.h. Для ее работы необходима функция сравнения двух сортируемых элементов массива (compare в нашем случае упорядочивает массивы по возрастанию строк-фамилий). Если мы хотим упорядочить массив по убыванию, нужно изменить возвращаемые значения).

3. Описание структуры (и необходимая ему константа l_name) перенесены в глобальную область (чтобы быть известным в функцииcompare).

4. Для упорядочения массива по другому полю надо изменить функцию сравнения. Вот, например, при сортировке по возрастанию года рождения она выглядит так:

int compare (const  void*man1, const  void* man2)

{int p;

 if ( (reinterpret_cast <const Man*>(man1))->birth_year <                                      (reinterpret_cast <const Man*>(man2))-> birth_year)   p=-1;

else if( (reinterpret_cast <const Man*>(man1))->birth_year ==                                      (reinterpret_cast <const Man*>(man2))-> birth_year)  p=0;

else p=1;

returnp;

}

А при сортировке по убыванию оклада так:

int compare (const  void*man1, const  void* man2)

{ return  (reinterpret_cast <const Man*>(man1))->pay  >                                      (reinterpret_cast <const Man*>(man2))-> pay   ?  -1: (reinterpret_cast <const Man*>(man1))->pay ==                                      (reinterpret_cast <const Man*>(man2))-> pay ? 0: 1;

}

Создание программы 7.

Бинарные файлы и передача структур в функцию

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

Представим программу в виде трех функций:

read_data(), которая формирует структуру и возвращает ее;

append2binfile(), которая получает структуру и имя файла, добавляет структуру в файл и возвращает признак успешно добавления;

print_from_bin(), которая по введенному номеру записи выводит ее на экран

Похожие материалы

Информация о работе

Тип:
Конспекты лекций
Размер файла:
234 Kb
Скачали:
0