21.02.2011, 23:06
общий
это ответ
Здравствуйте, Наталия!
Примерно так. Для вычисления ближайших дат предназначена функция Sum, добавляющая к заданной дате заданное число дней. Я не предусматривала её универсальное использование, поэтому корректно будет отрабатываться только положительное число дней не более одного месяца. При необходимости несложно доделать функцию так, чтобы можно было передавать в неё любое число дней, в том числе, отрицательное.
Проверено на Visual Studio в режиме компиляции Си. Будут вопросы, задавайте.
Удачи!
Приложение:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
struct TDate { //дата
unsigned int day;
unsigned int month;
unsigned int year;
};
struct TPerson { //человек
char name [20];
char surname [20];
char secname [20];
struct TDate bday;
};
struct TDate InputDate () //ввод даты
{
struct TDate buf;
do { //повторять, пока не пройдёт проверку на корректность
do {
printf ("Enter day: ");
scanf ("%i", &buf.day);
} while (buf.day<=0 || buf.day>31);
do {
printf ("Enter month: ");
scanf ("%i", &buf.month);
} while (buf.month<=0 || buf.month>12);
do {
printf ("Enter year: ");
scanf ("%i", &buf.year);
} while (buf.year<=0);
} while (!CheckDate(buf));
return buf;
}
struct TPerson InputPerson () //ввод человека
{
struct TPerson buf;
printf ("Enter fio: ");
scanf ("%s", buf.surname);
scanf ("%s", buf.name);
scanf ("%s", buf.secname);
buf.bday = InputDate ();
return buf;
}
int IsLeap (int year) //проверка на високосность (1 - да, 0 - нет)
{
return ((year%100!=0 && year%4==0) || year%400==0);
}
int CheckDate (struct TDate dt) //проверка даты на корректность (1 - да, 0 - нет)
{
if (dt.month!=2) {
if (((dt.month<7 && dt.month%2==0) || (dt.month>7 && dt.month%2!=0))&& dt.day==31) return 0;
} else {
if (dt.day>29) return 0;
if (!IsLeap(dt.year) && dt.day==29) return 0;
}
return 1;
}
void Sum (struct TDate *dt, unsigned int days) //увеличение даты dt на заданное количество дней (только положительное число, в пределах месяца)
{
int d = dt->day+days;
if (dt->month!=2) {
if (d<31) {dt->day = d; return;}
if ((dt->month<7 && dt->month%2==0) || (dt->month>7 && dt->month%2!=0)){
dt->day = d-30;
if ((dt->month + 1)>12) {dt->month = 1; dt->year = dt->year+1;}
else dt->month = dt->month+1;
return;
} else {
if (d==31) dt->day = d;
else {
dt->day = d-31;
if ((dt->month + 1)>12) {dt->month = 1; dt->year = dt->year+1;}
else dt->month = dt->month+1;
}
return;
}
} else {
if (d<29) {dt->day = d; return;}
if (!IsLeap(dt->year)){
dt->day = d-28;
dt->month = dt->month+1;
return;
} else {
if (d==29) dt->day = d;
else {
dt->day = d-29;
dt->month = dt->month+1;
}
return;
}
}
}
int EqualDate (struct TDate dt1, struct TDate dt2) //сравнение дат на равенство месяца и дня
{
if (dt1.day==dt2.day && dt1.month==dt2.month) return 1;
else return 0;
}
void PrintPerson (struct TPerson p) //печать человека
{
printf ("\nFIO: %s %s %s", p.surname, p.name, p.secname);
printf ("\nBirthday: %i.%i.%i\n", p.bday.day, p.bday.month, p.bday.year);
}
int main (int argc, char* argv[])
{
struct TPerson *bd = NULL;
int n, i, j;
struct TDate tmp;
printf ("Enter number of records: "); //ввод
scanf ("%i", &n);
bd = (struct TPerson*) malloc (sizeof(struct TPerson)*n); //выделение памяти
for (i=0; i<n; i++)
bd[i] = InputPerson ();
while (1) { //бесконечный цикл
printf ("\nEnter date\n");
tmp = InputDate(); //ввод запрашиваемой даты
printf ("List of persons:");
for (i=0; i<7; i++) { //поиск подходящих людей в пределах недели
for (j=0; j<n; j++) //сравнение с текущей
if (EqualDate (tmp, bd[j].bday)) PrintPerson (bd[j]);
Sum (&tmp, 1); //увеличение на день
}
}
free (bd); //освобождение памяти
return 0;
}