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


#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
#include <windows.h>   /* для SetConsoleCP/SetConsoleOutputCP, если Windows */

#define TASK 1   /* 1, 2 или 3 — переключение задания */

/* ---------- Утилиты ---------- */

/* Безопасное чтение строки с пробелами */
static void readLine(char *buf, int size) {
    if (fgets(buf, size, stdin)) {
        size_t len = strlen(buf);
        if (len && buf[len - 1] == '\n') buf[len - 1] = '\0';
    }
}

/* Сброс буфера ввода после scanf */
static void clearInput(void) {
    int c;
    while ((c = getchar()) != '\n' && c != EOF) {}
}

/* Сравнение для qsort (по убыванию double) */
typedef struct { char fio[128]; double avg; char gender[8]; } RankItem;
static int cmpRankDesc(const void *a, const void *b) {
    double da = ((const RankItem*)a)->avg;
    double db = ((const RankItem*)b)->avg;
    if (da < db) return 1;
    if (da > db) return -1;
    return 0;
}

static int cmpInt(const void *a, const void *b) {
    return (*(const int*)a) - (*(const int*)b);
}

static double medianInt(int *arr, int n) {
    if (n == 0) return 0.0;
    qsort(arr, n, sizeof(int), cmpInt);
    if (n % 2 == 1) return arr[n / 2];
    return (arr[n / 2 - 1] + arr[n / 2]) / 2.0;
}

/* ============================================================
   ЗАДАНИЕ 1. Классный журнал
   ============================================================ */
#if TASK == 1

#define MAX_REC 200

typedef struct {
    char surname[50];
    char name[50];
    char patronymic[50];
    char gender[8];        /* "М" или "Ж" */
    char className[20];
    char subject[50];
    int  grade;
} JournalRecord;

int main(void) {
    setlocale(LC_ALL, "Russian");
#ifdef _WIN32
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
#endif

    JournalRecord journal[MAX_REC];
    int n = 0;
    printf("Сколько записей ввести? ");
    if (scanf("%d", &n) != 1) return 1;
    clearInput();
    if (n > MAX_REC) n = MAX_REC;

    for (int i = 0; i < n; ++i) {
        printf("\n--- Запись %d ---\n", i + 1);
        printf("Фамилия: ");   readLine(journal[i].surname, 50);
        printf("Имя: ");       readLine(journal[i].name, 50);
        printf("Отчество: ");  readLine(journal[i].patronymic, 50);
        printf("Пол (М/Ж): "); readLine(journal[i].gender, 8);
        printf("Класс: ");     readLine(journal[i].className, 20);
        printf("Предмет: ");   readLine(journal[i].subject, 50);
        printf("Оценка: ");
        scanf("%d", &journal[i].grade);
        clearInput();
    }

    /* Группировка по ФИО */
    RankItem items[MAX_REC];
    int itemCount = 0;

    for (int i = 0; i < n; ++i) {
        char fio[128];
        snprintf(fio, sizeof(fio), "%s %s %s",
                 journal[i].surname, journal[i].name, journal[i].patronymic);

        int found = -1;
        for (int j = 0; j < itemCount; ++j)
            if (strcmp(items[j].fio, fio) == 0) { found = j; break; }

        if (found < 0) {
            found = itemCount++;
            strcpy(items[found].fio, fio);
            items[found].avg = 0.0;
            strcpy(items[found].gender, journal[i].gender);
            /* храним сумму в avg, а кол-во во вспомогательном массиве */
        }
        /* накопим в avg сумму, потом поделим */
        items[found].avg += journal[i].grade;
    }

    /* Посчитаем количество оценок на каждого — вторая проходка */
    int counts[MAX_REC] = {0};
    for (int i = 0; i < n; ++i) {
        char fio[128];
        snprintf(fio, sizeof(fio), "%s %s %s",
                 journal[i].surname, journal[i].name, journal[i].patronymic);
        for (int j = 0; j < itemCount; ++j)
            if (strcmp(items[j].fio, fio) == 0) { counts[j]++; break; }
    }
    for (int j = 0; j < itemCount; ++j)
        if (counts[j] > 0) items[j].avg /= counts[j];

    /* Ранжирование */
    qsort(items, itemCount, sizeof(RankItem), cmpRankDesc);

    printf("\n=== Рейтинг учеников ===\n");
    for (int i = 0; i < itemCount; ++i)
        printf("%d. %s — средний балл %.2f\n", i + 1, items[i].fio, items[i].avg);

    printf("\nКоличество учеников: %d\n", itemCount);

    /* Успеваемость по полу */
    double sumM = 0, sumF = 0;
    int cntM = 0, cntF = 0;
    for (int i = 0; i < itemCount; ++i) {
        if (strcmp(items[i].gender, "М") == 0) { sumM += items[i].avg; cntM++; }
        else                                   { sumF += items[i].avg; cntF++; }
    }
    printf("\n=== Успеваемость по полу ===\n");
    printf("Мужчины: %d, средний балл: %.2f\n", cntM, cntM ? sumM / cntM : 0.0);
    printf("Женщины: %d, средний балл: %.2f\n", cntF, cntF ? sumF / cntF : 0.0);

    return 0;
}

/* ============================================================
   ЗАДАНИЕ 2. Библиотека
   ============================================================ */
#elif TASK == 2

#define MAX_BOOKS 100
#define MAX_AUTH  3

typedef struct {
    char authors[MAX_AUTH][100];
    int  authorCount;
    char title[200];
    char isbn[30];
    int  year;
} Book;

int main(void) {
    setlocale(LC_ALL, "Russian");
#ifdef _WIN32
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
#endif

    Book books[MAX_BOOKS];
    int n = 0;
    printf("Сколько книг ввести? ");
    if (scanf("%d", &n) != 1) return 1;
    clearInput();
    if (n > MAX_BOOKS) n = MAX_BOOKS;

    for (int i = 0; i < n; ++i) {
        printf("\n--- Книга %d ---\n", i + 1);
        int k;
        printf("Количество авторов (1-3): ");
        scanf("%d", &k);
        clearInput();
        if (k < 1) k = 1;
        if (k > MAX_AUTH) k = MAX_AUTH;
        books[i].authorCount = k;

        for (int j = 0; j < k; ++j) {
            printf("Автор %d: ", j + 1);
            readLine(books[i].authors[j], 100);
        }
        printf("Название: "); readLine(books[i].title, 200);
        printf("ISBN: ");     readLine(books[i].isbn, 30);
        printf("Год: ");
        scanf("%d", &books[i].year);
        clearInput();
    }

    char keyword[100];
    printf("\nВведите ключевое слово: ");
    readLine(keyword, 100);

    printf("\n=== Найденные издания ===\n");
    int found = 0;
    for (int i = 0; i < n; ++i) {
        if (strstr(books[i].title, keyword)) {
            found = 1;
            printf("Название: %s\nАвторы: ", books[i].title);
            for (int j = 0; j < books[i].authorCount; ++j) {
                if (j) printf(", ");
                printf("%s", books[i].authors[j]);
            }
            printf("\nГод издания: %d\n\n", books[i].year);
        }
    }
    if (!found) printf("Книг с таким словом не найдено.\n");
    return 0;
}

/* ============================================================
   ЗАДАНИЕ 3. Сотрудники предприятия
   ============================================================ */
#elif TASK == 3

#define N_EMP 15

typedef struct {
    char surname[50];
    char name[50];
    char patronymic[50];
    int  age;
    char gender[8];
    char position[60];
} Employee;

int main(void) {
    setlocale(LC_ALL, "Russian");
#ifdef _WIN32
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
#endif

    Employee e[N_EMP];

    for (int i = 0; i < N_EMP; ++i) {
        printf("\n--- Сотрудник %d ---\n", i + 1);
        printf("Фамилия: ");   readLine(e[i].surname, 50);
        printf("Имя: ");       readLine(e[i].name, 50);
        printf("Отчество: ");  readLine(e[i].patronymic, 50);
        printf("Возраст: ");
        scanf("%d", &e[i].age);
        clearInput();
        printf("Пол (М/Ж): "); readLine(e[i].gender, 8);
        printf("Должность: "); readLine(e[i].position, 60);
    }

    int agesAll[N_EMP], agesM[N_EMP], agesF[N_EMP];
    int nAll = 0, nM = 0, nF = 0;
    double sumAll = 0, sumM = 0, sumF = 0;

    for (int i = 0; i < N_EMP; ++i) {
        agesAll[nAll++] = e[i].age;
        sumAll += e[i].age;
        if (strcmp(e[i].gender, "М") == 0) {
            agesM[nM++] = e[i].age;
            sumM += e[i].age;
        } else {
            agesF[nF++] = e[i].age;
            sumF += e[i].age;
        }
    }

    printf("\n=== Статистика по полу ===\n");
    printf("Мужчин: %d, средний возраст: %.2f, медианный: %.2f\n",
           nM, nM ? sumM / nM : 0.0, medianInt(agesM, nM));
    printf("Женщин: %d, средний возраст: %.2f, медианный: %.2f\n",
           nF, nF ? sumF / nF : 0.0, medianInt(agesF, nF));

    printf("\n=== Статистика по всем сотрудникам ===\n");
    printf("Средний возраст: %.2f\n", nAll ? sumAll / nAll : 0.0);
    printf("Медианный возраст: %.2f\n", medianInt(agesAll, nAll));

    return 0;
}

#else
#error "Неизвестное значение TASK"
#endif