C中的函数有问题

qoefvg9y  于 2022-12-29  发布在  其他
关注(0)|答案(1)|浏览(84)

在我的程序中,我要求用户输入一个日期(只能是整数,如12 31 2019 367)和他们添加到该日期的天数。在我的一个函数中,这正是我正在做的事情。
用户输入12 31 2019 367,程序本应打印1 1 2021,但却打印了1 1 2020(晚了一年)......
我做了什么(抱歉有很多代码,我尽量保持它简单和干净):

int days_in_month[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
                      
void add_days_to_date(int *mm, int *dd, int *yy, int days_left_to_add)
{
  int days_left_in_month;
  while(days_left_in_month > 0)
  {
    days_left_in_month = days_in_month[*mm] - *dd;
 //   days_left_in_month = days_in_month[*mm] - *dd;
    if (days_in_month[2] && is_leap_year(*yy) == true)
    {
      days_left_in_month++;
    }
   } // end while
   printf("after while\n");
    if(days_left_to_add > days_left_in_month)
    {
      days_left_to_add -= days_left_in_month;
      *dd = 1;
      if(*mm == 12)
      {
        *mm = 1;
        (*yy)++;
      }
      else
      {
        (*mm)++;
      }
    }
    else
    {
      *dd += days_left_to_add;
      days_left_to_add = 0;
    }
}
int main()
{
  int mm, dd, yy, days_left_to_add;
  printf("Please enter a date between the years 1800 and 10000 in the format mm dd yy and provide the number of days to add to this date:\n");
  scanf("%d %d %d %d", &mm, &dd, &yy, &days_left_to_add);
 // printf("\nREAD\n");
  //These are pointers, so they have to be at certain location i.e. int* mm = &mm
  add_days_to_date(&mm, &dd, &yy, days_left_to_add);
  printf("%d %d %d\n", mm, dd, yy);
}

输入后得到的结果:
输入:2019年12月31日367
产量:1 1 2020(本应为1 1 2021)

fcy6dtqo

fcy6dtqo1#

函数中的循环需要是while (days_left_to_add > 0),并且应该覆盖整个函数(然后需要做一些小的调整),实际上,你只需要加上一个月,假设你的输入是2019-12-31,你就会得到2020-01-01。
您的代码应该验证输入日期。
这段代码可以工作,至少对于许多类似于您的示例的测试用例是这样。

/* SO 74925-5084 */
#include <stdio.h>
#include <stdbool.h>

static const int days_in_month[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

static bool is_leap_year(int year)
{
    if (year % 4 != 0)
        return false;
    if (year % 100 != 0)
        return true;
    if (year % 400 != 0)
        return false;
    return true;
}

static void add_days_to_date(int *mm, int *dd, int *yy, int days)
{
    while (days > 0)
    {
        int days_left_in_month = days_in_month[*mm] - *dd + 1;
        if (*mm == 2 && is_leap_year(*yy))
            days_left_in_month++;
        //printf("DAYS = %2d, DLIM = %2d, leap(%4d) = %s\n",
        //       days, days_left_in_month, *yy, is_leap_year(*yy) ? "true" : "false");
        if (days >= days_left_in_month)
        {
            days -= days_left_in_month;
            *dd = 1;
            if (*mm == 12)
            {
                *mm = 1;
                (*yy)++;
            }
            else
            {
                (*mm)++;
            }
        }
        else
        {
            *dd += days;
            days = 0;
        }
        // This is informative while debugging
        printf("%.4d-%.2d-%.2d + %d\n", *yy, *mm, *dd, days);
    }
}

int main(void)
{
    int mm, dd, yy, days_left_to_add;
    printf("Please enter a date between the years 1800 and 10000 in the format mm dd yyyy\n"
           "and provide the positive number of days to add to this date:\n");
    if (scanf("%d %d %d %d", &mm, &dd, &yy, &days_left_to_add) != 4)
    {
        fprintf(stderr, "Failed to read 4 numbers\n");
        return 1;
    }
    printf("Input: %.4d-%.2d-%.2d + %d\n", yy, mm, dd, days_left_to_add);

    /* Data validation */
    if (days_left_to_add <= 0)
    {
        fprintf(stderr, "The number of days to add must be a positive number (unlike %d)\n",
                days_left_to_add);
        return 1;
    }
    if (yy < 1800 || yy > 10000)
    {
        fprintf(stderr, "Year %d is outside the range 1800..10000\n", yy);
        return 1;
    }
    if (mm < 1 || mm > 12)
    {
        fprintf(stderr, "Month %d is outside the range 1..12\n", mm);
        return 1;
    }
    int dim = days_in_month[mm];
    if (mm == 2 && is_leap_year(yy))
        dim++;
    if (dd < 1 || dd > dim)
    {
        fprintf(stderr, "Day %d is outside the range 1..%d\n", dd, dim);
        return 1;
    }

    add_days_to_date(&mm, &dd, &yy, days_left_to_add);
    printf("%d %d %d\n", mm, dd, yy);
    return 0;
}

样本运行(根据ad41.c创建的程序ad41):

$ ad41
Please enter a date between the years 1800 and 10000 in the format mm dd yyyy
and provide the positive number of days to add to this date:
12 31 2019 367
Input: 2019-12-31 + 367
2020-01-01 + 366
2020-02-01 + 335
2020-03-01 + 306
2020-04-01 + 275
2020-05-01 + 245
2020-06-01 + 214
2020-07-01 + 184
2020-08-01 + 153
2020-09-01 + 122
2020-10-01 + 92
2020-11-01 + 61
2020-12-01 + 31
2021-01-01 + 0
1 1 2021
$ ad41
Please enter a date between the years 1800 and 10000 in the format mm dd yyyy
and provide the positive number of days to add to this date:
12 31 2018 60
Input: 2018-12-31 + 60
2019-01-01 + 59
2019-02-01 + 28
2019-03-01 + 0
3 1 2019
$ ad41
Please enter a date between the years 1800 and 10000 in the format mm dd yyyy
and provide the positive number of days to add to this date:
12 31 2019 60
Input: 2019-12-31 + 60
2020-01-01 + 59
2020-02-01 + 28
2020-02-29 + 0
2 29 2020
$

相关问题