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


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

/* Проверка високосного года (григорианский календарь) */
int is_leap(int year)
{
    return ( (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0) );
}

/* Количество дней в месяце для заданного года */
int days_in_month(int month, int year)
{
    switch (month) {
    case 1: case 3: case 5: case 7: case 8: case 10: case 12:
        return 31;
    case 4: case 6: case 9: case 11:
        return 30;
    case 2:
        return is_leap(year) ? 29 : 28;
    default:
        return 0; /* неверный месяц */
    }
}

/* Проверка корректности даты */
int is_valid_date(int d, int m, int y)
{
    /* Ограничиваем "разумный" диапазон лет: 1..3000 */
    if (y <= 0 || y > 3000) {
        return 0; /* нулевой, отрицательный или слишком большой год */
    }
    if (m < 1 || m > 12) {
        return 0;
    }

    int dim = days_in_month(m, y);
    if (dim == 0) {
        return 0;
    }

    if (d < 1 || d > dim) {
        return 0;
    }

    return 1;
}

/* Чтение строки с обрезкой \n и вычиткой остатка при переполнении */
int input_line(char* buf, int size)
{
    if (!fgets(buf, size, stdin)) {
        return 0; /* EOF или ошибка ввода */
    }

    size_t len = strlen(buf);
    if (len > 0 && buf[len - 1] == '\n') {
        buf[len - 1] = '\0';
        return 1;
    }

    /* Строка не влезла – вычитываем остаток до конца строки */
    int ch;
    while ((ch = getchar()) != '\n' && ch != EOF) {}
    return 1;
}

/* Разбор строки даты: допускаем разделители ' ', '.', '-', '/' */
int parse_date(const char* line, int* d, int* m, int* y)
{
    char tmp[256];
    char extra[16];
    int n;

    /* Копируем строку в tmp, чтобы можно было её менять */
    strncpy(tmp, line, sizeof(tmp) - 1);
    tmp[sizeof(tmp) - 1] = '\0';

    /* Заменяем точки, дефисы и слэши на пробелы */
    for (int i = 0; tmp[i] != '\0'; ++i) {
        if (tmp[i] == '.' || tmp[i] == '-' || tmp[i] == '/') {
            tmp[i] = ' ';
        }
    }

    /* Пытаемся считать три целых и проверить, что мусора нет */
    n = sscanf(tmp, "%d %d %d %15s", d, m, y, extra);
    if (n != 3) {
        return 0;
    }

    return 1;
}

/* Безопасный ввод одной даты: просит повторить, пока дата не станет корректной */
void input_date(const char* prompt, int* d, int* m, int* y)
{
    char buf[256];
    int ok = 0;

    while (!ok) {
        printf("%s (дд мм гггг или дд.мм.гггг): ", prompt);

        if (!input_line(buf, sizeof(buf))) {
            printf("\nКонец ввода (EOF). Программа завершена.\n");
            exit(0);
        }

        if (!parse_date(buf, d, m, y)) {
            printf("Ошибка ввода. Введите три ЦЕЛЫХ числа (например, 19 12 2001 или 19.12.2001).\n");
            continue;
        }

        if (!is_valid_date(*d, *m, *y)) {
            printf("Некорректная дата. Проверьте день, месяц и год.\n");
            continue;
        }

        ok = 1;
    }
}

/* Перевод даты в количество дней с 01.01.0001 (пролептический григорианский календарь) */
long long date_to_days(int d, int m, int y)
{
    long long yy = y - 1;

    /* Дни в полных годах до года y */
    long long days = yy * 365
                   + yy / 4
                   - yy / 100
                   + yy / 400;

    /* Дни в полных месяцах текущего года */
    for (int month = 1; month < m; ++month) {
        days += days_in_month(month, y);
    }

    /* Дни текущего месяца */
    days += d;

    return days;
}

/* Выводит, насколько дата A старше/младше даты B (в днях) */
void compare_two(const char* nameA, int dA, int mA, int yA,
                 const char* nameB, int dB, int mB, int yB)
{
    long long tA = date_to_days(dA, mA, yA);
    long long tB = date_to_days(dB, mB, yB);
    long long diff = tA - tB;

    printf("\nСравнение %s и %s:\n", nameA, nameB);

    if (diff == 0) {
        printf("%s и %s — одна и та же дата.\n", nameA, nameB);
    } else if (diff > 0) {
        /* A позже B => человек младше */
        printf("%s младше, чем %s, на %lld день(дней).\n", nameA, nameB, diff);
    } else {
        /* A раньше B => человек старше */
        printf("%s старше, чем %s, на %lld день(дней).\n", nameA, nameB, -diff);
    }
}

int main(void)
{
    /* Русскоязычный интерфейс: вывод в UTF‑8 */
    SetConsoleOutputCP(65001);
    /* Ввод оставляем в стандартной кодировке консоли */

    int d1, m1, y1;
    int d2, m2, y2;
    int d3, m3, y3;

    printf("Программа сравнивает три даты рождения.\n\n");

    input_date("Введите первую дату рождения",  &d1, &m1, &y1);
    input_date("Введите вторую дату рождения",  &d2, &m2, &y2);
    input_date("Введите третью дату рождения",  &d3, &m3, &y3);

    /* Если все три даты совпадают – отдельное сообщение */
    if (d1 == d2 && m1 == m2 && y1 == y2 &&
        d1 == d3 && m1 == m3 && y1 == y3) {
        printf("\nВсе три даты совпадают.\n");
    } else {
        compare_two("первая дата",  d1, m1, y1, "вторая дата",  d2, m2, y2);
        compare_two("первая дата",  d1, m1, y1, "третья дата",  d3, m3, y3);
        compare_two("вторая дата",  d2, m2, y2, "третья дата",  d3, m3, y3);
    }

    printf("\nНажмите Enter для выхода...\n");
    getchar(); /* ждём Enter */

    return 0;
}