Посчитать количество дней между двумя событиями - 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
для получения количества дней от начала следующего года до второго события.
- Увеличивается значение переменной
- Выводится сообщение с количеством дней от первого события до второго.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д