Загрузка данных


#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>

#define MAX 50

typedef struct {
    char surname[40];
    char name[40];
    char patronymic[40];
    char fac[30];
    char department[40];
    char degree[20];   // kandidat / doktor / net
    char title[20];    // docent / professor / net
    char post[30];     // docent / starshiy_prepod / assistent и т.д.
    int  year;
    char gender[10];
    char address[60];
} TEmployee;

TEmployee list[MAX];
int count = 0;

// Кастомная функция сравнения строк из примера отчета
int cmpStr(const char *a, const char *b) {
    int i = 0;
    while (a[i] && b[i]) {
        if (a[i] > b[i]) return  1;
        if (a[i] < b[i]) return -1;
        i++;
    }
    if (a[i] == '\0' && b[i] == '\0') return 0;
    return (a[i] == '\0') ? -1 : 1;
}

void loadFile(void) {
    FILE *f = fopen("input.txt", "r");
    if (!f) { printf("Fail input.txt ne nayden!\n"); return; }
    count = 0;
    while (count < MAX &&
           fscanf(f, "%s %s %s %s %s %s %s %s %d %s %s",
                  list[count].surname, list[count].name, list[count].patronymic,
                  list[count].fac, list[count].department, list[count].degree,
                  list[count].title, list[count].post, &list[count].year,
                  list[count].gender, list[count].address) == 11)
        count++;
    fclose(f);
}

void saveFile(void) {
    int i;
    FILE *f = fopen("input.txt", "w");
    if (!f) { printf("Oshibka otkrytiya fayla!\n"); return; }
    for (i = 0; i < count; i++)
        fprintf(f, "%s %s %s %s %s %s %s %s %d %s %s\n",
                list[i].surname, list[i].name, list[i].patronymic,
                list[i].fac, list[i].department, list[i].degree,
                list[i].title, list[i].post, list[i].year,
                list[i].gender, list[i].address);
    fclose(f);
    printf("Dannie sohraneni.\n");
}

void printList(void) {
    int i;
    printf("\n%-12s %-10s %-12s %-8s %-12s %-10s %-10s %-12s %4s %-4s %-15s\n",
           "Surname", "Name", "Patronymic", "Fac", "Depart", "Degree", "Title", "Post", "Year", "Gen", "Address");
    printf("------------------------------------------------------------------------------------------------------------------------\n");
    for (i = 0; i < count; i++)
        printf("%-12s %-10s %-12s %-8s %-12s %-10s %-10s %-12s %4d %-4s %-15s\n",
               list[i].surname, list[i].name, list[i].patronymic,
               list[i].fac, list[i].department, list[i].degree,
               list[i].title, list[i].post, list[i].year,
               list[i].gender, list[i].address);
}

void addRecord(void) {
    if (count >= MAX) { printf("Massiv polon!\n"); return; }
    printf("Surname: ");    scanf("%s", list[count].surname);
    printf("Name: ");       scanf("%s", list[count].name);
    printf("Patronymic: "); scanf("%s", list[count].patronymic);
    printf("Faculty: ");    scanf("%s", list[count].fac);
    printf("Department: "); scanf("%s", list[count].department);
    printf("Degree: ");     scanf("%s", list[count].degree);
    printf("Title: ");      scanf("%s", list[count].title);
    printf("Post: ");       scanf("%s", list[count].post);
    printf("Birth Year: "); scanf("%d", &list[count].year);
    printf("Gender: ");     scanf("%s", list[count].gender);
    printf("Address: ");    scanf("%s", list[count].address);
    count++;
    printf("Dobavleno.\n");
}

void editRecord(void) {
    char key[40];
    int i, found = 0;
    printf("Surname dlya korrektury: "); scanf("%s", key);
    for (i = 0; i < count; i++) {
        if (strcmp(list[i].surname, key) == 0) {
            printf("Novaya stepen', zvanie, dolzhnost' i adres (cherez probel): ");
            scanf("%s %s %s %s", list[i].degree, list[i].title, list[i].post, list[i].address);
            printf("Izmeneno.\n");
            found = 1;
            break;
        }
    }
    if (!found) printf("Zapis ne naydena.\n");
}

void deleteRecord(void) {
    char key[40];
    int i, j, found = 0;
    printf("Surname dlya udaleniya: "); scanf("%s", key);
    for (i = 0; i < count; i++) {
        if (strcmp(list[i].surname, key) == 0) {
            for (j = i; j < count - 1; j++)
                list[j] = list[j + 1];
            count--;
            printf("Udaleno.\n");
            found = 1;
            break;
        }
    }
    if (!found) printf("Zapis ne naydena.\n");
}

void sortRecords(void) {
    int i, j;
    TEmployee tmp;
    for (i = 0; i < count - 1; i++)
        for (j = 0; j < count - i - 1; j++)
            if (cmpStr(list[j].surname, list[j+1].surname) > 0) {
                tmp = list[j];
                list[j] = list[j+1];
                list[j+1] = tmp;
            }
    printf("Otsoritirovano.\n");
}

void report(void) {
    if (count == 0) { printf("Baza dannih pusta.\n"); return; }

    char unique_faculties[MAX][30];
    int faculty_count = 0;
    int i, j, f;

    // Шаг 1: Поиск всех уникальных факультетов в базе
    for (i = 0; i < count; i++) {
        int found = 0;
        for (j = 0; j < faculty_count; j++) {
            if (strcmp(list[i].fac, unique_faculties[j]) == 0) {
                found = 1;
                break;
            }
        }
        if (!found) {
            strcpy(unique_faculties[faculty_count], list[i].fac);
            faculty_count++;
        }
    }

    printf("\n--- Formirovanie otchetov po facultetam ---\n");
    
    // Шаг 2: Генерация отдельного файла под каждый факультет
    for (f = 0; f < faculty_count; f++) {
        char filename[60];
        sprintf(filename, "Report_%s.txt", unique_faculties[f]);
        
        FILE *rep_file = fopen(filename, "w");
        if (!rep_file) { printf("Oshibka sozdaniya %s!\n", filename); continue; }
        
        // Заголовок без графы факультета согласно ТЗ задания
        fprintf(rep_file, "Sotrudniki %s (Tolko kandidati i doktora, bez grafi 'Faculty'):\n", unique_faculties[f]);
        fprintf(rep_file, "%-12s %-10s %-12s %-12s %-10s %-10s %-12s %4s %-4s %-15s\n", 
                "Surname", "Name", "Patronymic", "Depart", "Degree", "Title", "Post", "Year", "Gen", "Address");
        fprintf(rep_file, "------------------------------------------------------------------------------------------------------------\n");

        int records_in_file = 0;
        for (i = 0; i < count; i++) {
            if (strcmp(list[i].fac, unique_faculties[f]) == 0) {
                // Фильтр: только кандидаты ("kandidat") и доктора ("doktor")
                if (strcmp(list[i].degree, "kandidat") == 0 || strcmp(list[i].degree, "doktor") == 0) {
                    fprintf(rep_file, "%-12s %-10s %-12s %-12s %-10s %-10s %-12s %4d %-4s %-15s\n",
                            list[i].surname, list[i].name, list[i].patronymic,
                            list[i].department, list[i].degree, list[i].title,
                            list[i].post, list[i].year, list[i].gender, list[i].address);
                    records_in_file++;
                }
            }
        }
        fclose(rep_file);
        printf("Facultet '%s': zapisano %d chelovek v %s\n", unique_faculties[f], records_in_file, filename);
    }
}

int main(void) {
    int choice;
    loadFile();
    do {
        printf("\n------------------------------------------------------------\n");
        printf("1.List | 2.Add | 3.Delete | 4.Edit | 5.Sort | 6.Report | 0.Exit\n");
        printf("Choice: ");
        if (scanf("%d", &choice) != 1) {
            while (getchar() != '\n'); // Безопасная очистка буфера
            choice = -1;
        }
        switch (choice) {
            case 1: printList();    break;
            case 2: addRecord();    break;
            case 3: deleteRecord(); break;
            case 4: editRecord();   break;
            case 5: sortRecords();  break;
            case 6: report();       break;
            case 0: break;
            default: printf("Nevernyy vybor!\n");
        }
    } while (choice != 0);

    printf("Sohranit izmeneniya v input.txt? (1-da, 0-net): ");
    if (scanf("%d", &choice) != 1) choice = 0;
    if (choice == 1) saveFile();

    return 0;
}