Написать программу дополнения бинарного файла, сформированного в задаче 6.3, вводимыми с клавиатуры сведениями о сотрудниках.
Эту задачу можно разбить на две части: ввод сведений о сотрудниках в структуру и добавление этой информации в бинарный файл, поэтому в нашей программе будет две функции. Первая функция возвращает сформированную структуру, ничего не получая извне. Вторая получает структуру и имя файла и возвращает признак успешности добавления.
Для проверки правильности занесения данных в бинарный файл напишем еще одну функцию, которая будет по введенному номеру записи выводить ее на экран.
Ниже приведен текст программы.
#include < stdio.h>
#include < string.h>
#include < stdlib.h>
//#include < windows.h> // 0
const int l_name = 30;
struct Man {
char name[l_name + 1];
int birth_year;
float pay;
};
Man read_data();
int append2binfile(const Man & man, const char* filename);
int print_from_bin(const char * filename);
int main() {
bool contin; char y_n[2];
char filename[] = " dbase.bin";
do {
contin = false;
if (append2binfile(read_data(), filename)! =0) {
puts(" Ошибка при записи в файл"); return 1; }
puts (" Продолжить (у/п)? "); gets(y_n);
if ((y_n[0] == 'у') || (y_n[0] == 'Y')) contin == true;
} while (contin);
print_from_bin(filename);
return 0;
}
int append2binfile(const Man & man, const char* filename) {
FILE *fout;
if ((fout = fopen(filename, " ab")) == NULL) return 1;
int success = fwrite(& man, sizeof(man), 1, fout);
fclose(fout);
if (success == 1) return 0; else return 2;
}
int print_from_bin(const char * filename) {
int num;
Man man;
FILE *f;
if ((f = fopen(filename, " rb")) == NULL) return 1;
fseek(f, 0, SEEK_END);
int n_record = ftell(f) / sizeof (man);
while (true) {
puts(" Введите номер записи или -1: "); scanf(" %i", & num);
if (num < 0 || num > = n_record) break;
fseek(f, num * sizeof(man), SEEK_SET);
fread(& man, sizeof(man), 1. f);
// CharToOem(man.name, man.name); // 1
printf(" %30s%5i%10.2f\n", man.name, man.birth_year, man.pay);
}
return 0;
}
Man read_data() {
Man man;
char buf[80];
char name[l_name + 1];
puts(" Введите фамилию И.О. "); gets(name);
if (strlen(name) < l_name)
for (int i = stnen(name); i < l_name; i++) name[i] = ' ';
name[1_name] = 0;
// OemToChar(name, name); // 2
strncpy(man.name, name, l_name + 1);
do {
puts(" Введите год рождения "); gets(buf); }
while ((man.birth_year = atoi(buf)) == 0); // 3
do {
puts(" Введите оклад "); gets(buf); }
while (! (man.pay = atof(buf))); // 4
return man;
}
|
В функции ввода read_data предусмотрено заполнение пробелами оставшейся части строковой переменной name, чтобы формат имени был идентичен формату ввода в текстовом файле.