Посчитать количество дней между двумя событиями - 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);

Объяснение кода листинга программы

  1. Объявлена переменная days для хранения количества дней.
  2. Переменная num_year вычисляется как разность между годами второго и первого события минус единица.
  3. Переменная year равна году первого события плюс единица.
  4. В цикле for происходит подсчёт количества дней в полных годах между двумя событиями.
  5. В цикле выполняются следующие действия:
    • Увеличивается значение переменной days на сумму 365 и результат функции add_day_leap для года, увеличенного на i.
    • Вызывается функция get_days_end для получения количества дней от первого события до конца текущего года.
    • Вызывается функция get_days_begin для получения количества дней от начала следующего года до второго события.
  6. Выводится сообщение с количеством дней от первого события до второго.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

15   голосов , оценка 4.067 из 5
Похожие ответы