Требуется написать программу, которая упорядочивает описанный в предыдущей задаче файл по году рождения сотрудников.
Для сортировки применим метод выбора (из массива выбирается наименьший элемент и меняется местами с первым элементом, затем рассматриваются элементы, начиная со второго, наименьший из них меняется местами со вторым элементом и т.д.). Для упорядочивания требуется количество просмотров, на единицу меньшее, чем количество элементов в массиве (при последнем проходе меняются местами предпоследний и последний элементы массива).
#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;
}
Требуется написать две программы: первая считывает информацию из файла (в формате предыдущей задачи) и записывает ее в бинарный файл (информация в котором хранится во внутренней форме представления). Вторая программа по номеру записи корректирует оклад сотрудника в этом файле.
#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;
}
Требуется написать программу, которая выводит на экран содержимое бинарного файла, сформированного в задаче 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;
}
Требуется написать программу дополнения бинарного файла, сформированного в задаче 5, вводимыми с клавиатуры сведениями о сотрудниках.
Представим программу в виде трех функций:
read_data(), которая формирует структуру и возвращает ее;
append2binfile(), которая получает структуру и имя файла, добавляет структуру в файл и возвращает признак успешно добавления;
print_from_bin(), которая по введенному номеру записи выводит ее на экран
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.