简体   繁体   English

在 C 中遇到 function 问题

[英]Having trouble with a function in C

In my program, I am asking the user to input a date (in just integers such as 12 31 2019 367) and the number of days they add to it.在我的程序中,我要求用户输入一个日期(仅使用整数,例如 12 31 2019 367)以及他们添加到该日期的天数。 In one of my functions, this is precisely what I am doing.在我的一项职能中,这正是我正在做的。

The user inputs 12 31 2019 367, and the program is meant to print 1 1 2021, but instead prints 1 1 2020 (a year behind)...用户输入 12 31 2019 367,程序本应打印 1 1 2021,但打印的是 1 1 2020(落后一年)...

What I did (sorry for a lot of code, I tried to keep it simple and clean):我做了什么(抱歉有很多代码,我尽量保持简单和干净):

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);
}

What I got after inputs:输入后我得到了什么:

Inputs: 12 31 2019 367输入:12 31 2019 367

Output: 1 1 2020 (meant to be 1 1 2021) Output:1 1 2020(意味着 1 1 2021)

Your loop in the function needs to be while (days_left_to_add > 0) , and should cover the whole of the function (and then needs some minor adjustments).您在 function 中的循环需要while (days_left_to_add > 0) ,并且应该覆盖整个 function (然后需要进行一些小的调整)。 As it is, you add just one month, which given that your input is 2019-12-31 lands you on 2020-01-01.事实上,您只添加了一个月,假设您输入的是 2019-12-31,那么您将进入 2020-01-01。

Your code should validate the input date.您的代码应验证输入日期。

This code works, at least for a number of test cases similar to your example.此代码有效,至少对于许多类似于您的示例的测试用例。

/* 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;
}

Sample runs (program ad41 created from ad41.c ):示例运行(程序ad41ad41.c创建):

$ 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
$

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM