Посчитать количество дней между двумя событиями - C (СИ)
Формулировка задачи:
в функции interval считаю количество дней между двумя событиями, но не правильно, в чем проблема не понимаю, помогите
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<conio.h>
#include<locale.h>
struct hevent
{
int day, month, year;
char event[20];
};
void input(struct hevent *he)//ввод исторического события;
{
FILE *fhe;
char c;
int i=0, m;
if ((fhe=fopen("event.txt","a+"))!=NULL)
{
while((c=getc(fhe))!=EOF)
{
fscanf(fhe,"%d",&m);
fscanf(fhe,"%s",he[i].event);
fscanf(fhe,"%d",&he[i].day);
fscanf(fhe,"%d",&he[i].month);
fscanf(fhe,"%d",&he[i].year);
i++;
}
}
else printf("Error");
printf("Введите событие:");
scanf("%s", he[m].event);
printf("Введите день:");
scanf("%d", &he[m].day);
printf("Введите месяц:");
scanf("%d", &he[m].month);
printf("Введите год:");
scanf("%d", &he[m].year);
fprintf(fhe,"\n%d %s %d %d %d", m+1, he[m].event, he[m].day, he[m].month, he[m].year);
fclose(fhe);
}
void output(struct hevent *he)//вывод на экран списка исторических событий
{
FILE *fhe;
char c;
int i=0, j, m;
if ((fhe=fopen("event.txt","r"))!=NULL)
{
while((c=getc(fhe))!=EOF)
{
fscanf(fhe,"%d",&m);
fscanf(fhe,"%s",he[i].event);//событие
fscanf(fhe,"%d",&he[i].day);//день
fscanf(fhe,"%d",&he[i].month);//месяц
fscanf(fhe,"%d",&he[i].year);//год
i++;
}
}
else printf("Error");
printf("Исторические события:\n++++++++++++++++++++++++++++++\n");
printf("Событие\tДень\tМесяц\tГод\n");
for(j=0;j<m;j++)
{
printf("%s\t%d\t%d\t%d\n", he[j].event, he[j].day, he[j].month, he[j].year);
}
fclose(fhe);
}
int add_day_leap(unsigned int year) // Если год високосный добавить один день
{
return (!(year % 4) && (year % 100) || !(year % 400)) ? 1 : 0;
}
int get_days_month(int month, int year) // Вычисляем количество дней в месяце с учетом является ли год високосным
{
int days = 31;
switch(month)
{
case 2: days = 28 + add_day_leap(year); break;
case 4:
case 6:
case 9:
case 11: days = 30; break;
}
return days;
}
int get_days_begin(int day, int month, int year)// Считаем количество дней от начала года до текущей даты
{
int days = 0;
for(unsigned int i = 1; i < month; ++i)
{
days += get_days_month(i, year);
}
days += day; // складываем количество дней в месяцах от начала года
// с количеством дней в месяце когда произошло событие
return days;
}
int get_days_end(int day, int month, int year)// Считаем количество дней от текущей даты до конца года
{
int days = 0;
for(unsigned int i = month + 1; i <= 12; ++i)
{
days += get_days_month(i, year);
}
days += (get_days_month(month, year) - day);
return days;
}
void interval(struct hevent *he)//Вычислить интервал в днях, прошедший между двумя заданными историческими событиями
{
FILE *fhe;
char c;
int i = 0, m;
if ((fhe=fopen("event.txt","r"))!=NULL)
{
while((c=getc(fhe))!=EOF)
{
ungetc(c, fhe);
fscanf(fhe,"%d",&m);
fscanf(fhe,"%s",he[i].event);//событие
fscanf(fhe,"%d",&he[i].day);//день
fscanf(fhe,"%d",&he[i].month);//месяц
fscanf(fhe,"%d",&he[i].year);//год
i++;
}
}
else printf("Error");
fclose(fhe);
printf("\nИсторические события:\n++++++++++++++++++++++++++++++++++++++++++++\n");
printf("Номер события\tСобытие\tДень\tМесяц\tГод\n");
for(i = 0; i < m; ++i)
{
printf("%d\t\t%s\t%d\t%d\t%d\n",i, he[i].event, he[i].day, he[i].month, he[i].year);
}
int event_1, event_2;
printf("\nВведите номера событий для подсчета количества дней прошедших между ними:\n");
printf("Номер первого события: ");
scanf("%d", &event_1);
fflush(stdin);
printf("Номер второго события: ");
scanf("%d", &event_2);
fflush(stdin);
if((he[event_2].year < he[event_1].year) || (he[event_2].month < he[event_1].month) || (he[event_2].day < he[event_1].day)) // Проверим если событие 1 произошло позже события 2, то поменять их местами
{
i = event_1;
event_1 = event_2;
event_2 = i;
}
long days = 0;
int num_year = he[event_2].year - he[event_1].year - 1;
int year = he[event_1].year + 1;
for(i = 0; i < num_year; i++)
{
days += 365 + add_day_leap(year + i);
}
days += get_days_begin(he[event_2].day, he[event_2].month, he[event_2].year);
printf("Количество дней от %d/%d/%d до %d/%d/%d равно %d.\n"
,he[event_1].day
,he[event_1].month
,he[event_1].year
,he[event_2].day
,he[event_2].month
,he[event_2].year
,days);
}
int main (void)
{
setlocale(LC_ALL, "rus");
struct hevent st[1024];
int i;
while(1)
{
printf("\n++++++++++++++++++++++++++++++\nИсторические события\n++++++++++++++++++++++++++++++\n1.Ввести историческое событие\n2.Вывести исторические события\n3.Вычислить интервал в днях, между двумя заданными событиями\n4.Выход\nВведите номер команды:");
scanf("%d",&i);
switch(i)
{
case 1: input(st);break;
case 2: output(st);break;
case 3: interval(st);break;
case 4: exit(1); break;
default:printf("Error");
}
}
return 0;
}Решение задачи: «Посчитать количество дней между двумя событиями»
textual
Листинг программы
long days = 0;
int num_year = he[event_2].year - he[event_1].year - 1;
int year = he[event_1].year + 1;
// Надо посчитать количество дней в полных годах между двумя событиями
for(i = 0; i < num_year; ++i) {
days += 365 + add_day_leap(year + i);
}
// И в двух неполных годах
// от первого события до конца года
days += get_days_end(he[event_1].day, he[event_1].month, he[event_1].year); // !!!!! Вот эту !!!!!
// от начала года до второго события
days += get_days_begin(he[event_2].day, he[event_2].month, he[event_2].year);
printf("Количество дней от %d/%d/%d до %d/%d/%d равно %l.\n"
,he[event_1].day
,he[event_1].month
,he[event_1].year
,he[event_2].day
,he[event_2].month
,he[event_2].year
,days);
Объяснение кода листинга программы
- Объявлена переменная
daysдля хранения количества дней. - Переменная
num_yearвычисляется как разность между годами второго и первого события минус единица. - Переменная
yearравна году первого события плюс единица. - В цикле
forпроисходит подсчёт количества дней в полных годах между двумя событиями. - В цикле выполняются следующие действия:
- Увеличивается значение переменной
daysна сумму 365 и результат функцииadd_day_leapдля года, увеличенного наi. - Вызывается функция
get_days_endдля получения количества дней от первого события до конца текущего года. - Вызывается функция
get_days_beginдля получения количества дней от начала следующего года до второго события.
- Увеличивается значение переменной
- Выводится сообщение с количеством дней от первого события до второго.