#define _CRT_SECURE_NO_WARNINGS 1
#include <windows.h>
#include <stdio.h>
#include <conio.h>
//------------------------------------------------------------
// Структура - информация о компьютере
struct TComp {
char model[31], surname[31]; // модель и фамилия ответственного
struct {
int day, month, year; // день, месяц, год производства
} date;
int room; // номер комнаты
};
// ---------создание копии строки, но с символами
//---------------в верхнем регистре в Win1251
char *ANSIUpperCase(char *s, char *S) {
S = strcpy(S, s);
char *ch = S;
while (*ch) {
if (*ch >= 'a' && *ch <= 'z' || *ch >= 'а' && *ch <= 'я') *ch = *ch - 32;
if (*ch == 'ё') *ch = 'Ё';
ch++;
}
return S;
}
//----------первая часть: создание двоичного из текстового
void CreateBinaryFile(int argc, char* argv[]) {
if (argc<3) {
printf("Мало параметров\nPress any key");
_getch();
return;
}
FILE *ft = fopen(argv[2], "rt");
if (ft == NULL) {
printf("Error: не удалось открыть файл с исходными данными %s\n", argv[2]);
printf("Press any key "); _getch();
return;
}
FILE *fb = fopen(argv[1], "wb");
if (fb == NULL) {
fclose(ft);
printf("Error: не удалось создать двоичный файл %s\n", argv[1]);
printf("Press any key"); _getch();
return;
}
TComp Comp;
int kol = 0, nw = 1;
while (nw) {
fgets(Comp.model, 30, ft); // строка с названием модели
if (strcmp(Comp.model, "**") == 0 || feof(ft)) break; // проверка на конец файла
fscanf(ft, "%s\n", &Comp.surname);
fscanf(ft, "%d %d %d\n", &Comp.date.day, &Comp.date.month, &Comp.date.year);
fscanf(ft, "%d\n", &Comp.room);
nw = fwrite(&Comp, sizeof(Comp), 1, fb);
kol++;
}
if (nw != 1) printf("Error: Ошибка при записи");
fclose(ft);
fclose(fb);
printf("Создан двоичный файл из %d записей по %d байт\n", kol, sizeof(TComp));
printf("Press any key to continue");
_getch();
return;
}
//-------------- вторая часть: поиск в двоичном файле ----
void FindIVAN(int argc, char* argv[]) {
if (argc<2) {
printf("Мало параметров\nPress any key");
_getch();
return;
}
FILE *fb = fopen(argv[1], "rb");
if (fb == NULL) {
printf("Error: не удалось открыть двоичный файл %s\n", argv[1]);
printf("Press ENTER");
_getch();
return;
}
TComp Comp;
char SUp[31];
int kol = 0, nr = 1;
while (nr) {
nr = fread(&Comp, sizeof(Comp), 1, fb);
if (nr > 0) {
if (Comp.date.year == 1995 && strcmp(ANSIUpperCase(Comp.model, SUp), "IBM HC-486\n") == 0) {
printf("Найден %s%d года, комната %d\n", Comp.model, Comp.date.year, Comp.room);
kol++;
}
}
}
if (kol == 0)
printf("Данные, соответствующие запросу,не найдены\n");
else
printf("Всего найдено: %d\n", kol);
fclose(fb);
printf("Press any key to continue");
_getch();
return;
}
//-------третья часть: корректировка в двоичном файле ----
void CorrectFile(int argc, char* argv[]) {
if (argc<2) {
printf("Мало параметров\nPress any key");
_getch();
return;
}
FILE *fb = fopen(argv[1], "rb+");
if (fb == NULL) {
printf("Error: не удалось открыть двоичный файл %s\n", argv[1]);
printf("Press ENTER");
_getch();
return;
}
TComp Comp;
int kol = 0, nr = 1, nw = 1, flag;
nr = fread(&Comp, sizeof(Comp), 1, fb);
while (nr == 1 && nw == 1) {
printf("Считана запись:\n");
printf("%25s%20s%3d%3d%5d%4d\n", Comp.model, Comp.surname, Comp.date.day,
Comp.date.month, Comp.date.year, Comp.room);
flag = 0;
if (Comp.date.month < 1) { Comp.date.month = 1; flag = 1; }
if (Comp.date.month > 12) { Comp.date.month = 12; flag = 1; }
if (Comp.date.day < 1) { Comp.date.day = 1; flag = 1; }
if (Comp.date.month == 2 && Comp.date.day > 28 && (Comp.date.year % 4 != 0 || (Comp.date.year % 100 == 0 && (Comp.date.year / 100) % 4 != 0))) { Comp.date.day = 28; flag = 1; } // проверка на НЕ високосный год!
if (Comp.date.month == 2 && Comp.date.day > 29) { Comp.date.day = 29; flag = 1; } // Проверка как для високосного, так как в случае не високосного после верхней проверки день будет уже меньше 29
if ((Comp.date.month == 4 || Comp.date.month == 6 || Comp.date.month == 9 || Comp.date.month == 11) && Comp.date.day > 30) { Comp.date.day = 30; flag = 1; } // месяцы с 30 днями
if (Comp.date.day > 31) { Comp.date.day = 31; flag = 1; } // остальные месяцы, не рассмотренные выше имеют 31 день
if (Comp.room < 1) { Comp.room = 1; flag = 1; } // номер комнаты должен быть положительным
if (flag) {
kol++;
fseek(fb, 0 - sizeof(Comp), SEEK_CUR);
nw = fwrite(&Comp, sizeof(Comp), 1, fb);
fseek(fb, 0, SEEK_CUR);
printf("Сделана корректировка:\n");
printf("%25s%20s%3d%3d%5d%4d\n", Comp.model, Comp.surname, Comp.date.day,
Comp.date.month, Comp.date.year, Comp.room);
}
nr = fread(&Comp, sizeof(Comp), 1, fb);
}
if (kol == 0)
printf("Ни одной корректировки\n");
else
printf("Всего корректировок: %d\n", kol);
fclose(fb);
printf("Press any key to continue");
_getch();
return;
}
//------------------главная функция-----------------------
int main(int argc, char* argv[])
{
char ch;
SetConsoleOutputCP(1251);
do {
printf("\nN - создать новый тип.файл; F - сразу поиск; C - коррекция; E - конец.\nВаш выбор ? ");
ch = (char)getchar();
while (getchar() != '\n');
fflush(stdin);
ch = (char)toupper(ch);
switch (ch) {
//----------первая часть: создание двоичного из текстового
case 'N': CreateBinaryFile(argc, argv); break;
//-------------- вторая часть: поиск в двоичном файле ----
case 'F': FindIVAN(argc, argv); break;
//-------третья часть: корректировка в двоичном файле ----
case 'C': CorrectFile(argc, argv); break;
//-----------выход----------------------------------------
case 'E': return 0;
//--------------------------------------------------------
default:
printf("Нет такой команды\nPress any key");
getchar();
}
} while (ch != 'E');
return 0;
}