Загрузка данных
#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;
}