日期比较计划

时间:2017-07-30 04:32:17

标签: c

有人能发现我的代码有什么问题吗? 它应该简单地比较日期和最早应记录的日期,但只有我的第一个输入是。慢慢走过它看不出我的逻辑错误在哪里。

#include <stdio.h>

int main(void)
{
   int month=1, day=1, year=1;
   int fmonth=0, fday=0, fyear=0;

   while((month != 0) && (day != 0) && (year != 0))
   {
      printf("Enter the date: (0/0/0 to cancel) ");
      scanf("%d/%d/%d", &month, &day, &year);
      if(fyear < year)
      {
         fyear = year;
         fmonth = month;
         fday = day;
      }
      else if ((fyear == year) && (fmonth < month) && (fday <= day))
      {
         fyear=year;
         fmonth=month;
         fday=day;
      }
   }

   printf("Earliest Date is: %d/%d/%d\n", fmonth,fday,fyear);

   return 0;
}

6 个答案:

答案 0 :(得分:2)

哈,这很有趣。你的主要问题是你的比较被逆转了。 (并且您需要添加(month == fmonth)测试)您的第二个问题是验证用户输入完全失败 - 每次都会咬你。

首先,您想在分配之前检查(date < fdate),而不是(fdate < date),或者您将用更晚的日期覆盖您的早期日期(如yuchaun最初正确记录的那样)。

始终始终验证用户输入。大家都知道猫可能会踩到键盘上。至少,至少检查scanf的返回值,以确认您预期的转化次数为int,确实发生了(验证值是否有效月,日,年范围留给你。)

将这些碎片放在一起,并用一个简单的计数器取代"0/0/0"取消,以确定何时输入两个日期,你可以做类似的事情:

#include <stdio.h>

int main (void) {

    int month = 1, day = 1, year = 1,
        fmonth = 0, fday = 0, fyear = 0,
        n = 0;  /* simple counter - no need for 0/0/0 */

    while (1) { /* just loop until you have 2 dates */
        printf ("Enter the date: ");

        /* validate ALL User Input */
        if (scanf ("%d/%d/%d", &month, &day, &year) != 3) {
            fprintf (stderr, "error: invalid date, exiting.\n");
            return 1;
        }

        /* if no fdate or if (date < fdate) then fdate = date */
        if (!n || (year < fyear) || 
            ((year == fyear) && ((month < fmonth) || 
            ((month == fmonth) && (day < fday))))) {
            fyear = year;
            fmonth = month;
            fday = day;
        }
        if (++n == 2)   /* increment counter and test */
            break;
    }

    printf ("Earliest Date : %d/%d/%d\n", fmonth, fday, fyear);

    return 0;
}

示例使用/输出

$ ./bin/earlierdate
Enter the date: 12/21/1991
Enter the date: 12/22/1991
Earliest Date : 12/21/1991

$ ./bin/earlierdate
Enter the date: 12/22/1991
Enter the date: 12/21/1991
Earliest Date : 12/21/1991

遇到这样的问题时,请始终看How to debug small programs并且不要害怕和鸭子说话......它有效!

仔细检查并考虑所有答案,如果您有任何其他问题,请告诉我。

答案 1 :(得分:1)

代码中的一些错误包括:

  1. if (fyear < year):之前我说fyear = 2015,现在我扫描year = 2012。是2015 < 2012吗?那么,条件是reversed,对吧?
  2. 现在倒车的问题是fmonth=0, fday=0, fyear=0。假设,我扫描年份= 2012年。那么,检查(fyear > year)(0 > 2012)?它不会被更新。因此,请更改initialization
  3. 最后,如果您扫描0/0/0,并说出我们现在的fyear = 2012year = 0。所以,fyear > year2012 > 0,这将整个事情更新为0/0/0。我们需要注意when to scan因为while循环在检查上一次扫描之前执行整个操作。
  4. (fyear == year) && (fmonth < month) && (fday <= day)如果现在的月份少于前一个月怎么办?条件应为||
  5. 所以,我认为你可以画出这样的解决方案,

    #include <stdio.h>
    #include <limits.h>
    int main(void)
    {
    
      int fmonth=INT_MAX, fday=INT_MAX, fyear=INT_MAX, month=INT_MAX, year = INT_MAX, day = INT_MAX;
    
      while(month != 0 && year != 0 && day != 0)
      {
       if(year<fyear || (year==fyear && month<fmonth) || (year==fyear && month==fmonth && day<fday))
        {
          fyear = year;
          fmonth = month;
          fday = day;
        }
        printf("Enter the date: (0/0/0 to cancel) ");
        scanf("%d/%d/%d", &month, &day, &year);
      }
      printf("Earliest Date is: %d/%d/%d\n", fmonth,fday,fyear);
      return 0;
    }
    

答案 2 :(得分:1)

由于决策树很难调试和编写,因此首先应确保所有月份和日期都在适当的范围内。 然后,只需在这个可能混合的基数系统中为每个数字分配一个合适的权重:

 int days_total = w_y * years + w_m * months + w_d * days;

另一个日期也一样。比较简化为将此线性化日期与任何w_d&gt; = 1,w_m&gt; = 31,w_y&gt; = 366进行比较。

建议值为1,32和512,以获得最佳性能。

答案 3 :(得分:0)

当你输入的日期晚于存储的fyear /月/日时,你实际上覆盖了fyear,fmonth,fdays的值,我认为这不是你的意图

我得到以下输出:

$ ./a.out
Enter the date: (0/0/0 to cancel) 1/2/3
Enter the date: (0/0/0 to cancel) 3/4/5
Enter the date: (0/0/0 to cancel) 0/0/0
Earliest Date is: 3/4/5
$ ./a.out
Enter the date: (0/0/0 to cancel) 3/4/5
Enter the date: (0/0/0 to cancel) 1/2/3
Enter the date: (0/0/0 to cancel) 0/0/0
Earliest Date is: 3/4/5
$ ./a.out
Enter the date: (0/0/0 to cancel) 1/2/3
Enter the date: (0/0/0 to cancel) 0/0/0
Earliest Date is: 1/2/3

所以它不仅仅是被捕获的第一个输入,但记录的日期是最新的,而不是最早的。

答案 4 :(得分:0)

在比较

时你犯了一个小错误
if(fyear < year)

由于您将用户输入保存在变量year中,因此您只记录最新的日期,而不是最早的日期。

但是只是更改操作符在这里不起作用,您需要重新实现此程序。尝试对比较最佳效果进行成像。

提示:

  • 也许尝试使用天数和月份的范围(1&lt; = day&lt; = 28,30,31和1&lt; = month&lt; = 12)
  • 你想在第二个if语句中比较第一年的想法是可以的,现在尝试相同的月份和日期:

    if(year <= fyear) {
        if(month <= fmonth) {
            if(day <= day) {
                fday = day;
                fmonth = month;
                fyear = year;
            }else{
                /* nothing happens, since date 
                 * is later than the current */
            }
        }else{
            // your logic here
        }
    }else{
        // your logic here
    }
    
  • 当它们都是0时,可能会立即将值分配给fyear,fmonth和fday变量。因为当与输入日期进行比较时,会检查输入日期早于初始值的if语句(0 / 0/0)日期总是失败。

答案 5 :(得分:0)

在这里,我编辑了您的代码并包含了一些语句,以使程序用户友好。我认为这将确保您的要求。而且你还要考虑,2月29日(闰年)月份,年份日期&gt; 0

   #include<stdio.h>

int main(void)
{

   int month=1, day=1, year=1;
   int fmonth, fday, fyear;

   printf("Enter the date: (0/0/0 to cancel)\n ");
   scanf("%d/%d/%d", &fday, &fmonth, &fyear);
   while(1)
   {

   printf("1.Do you want to continue.\n2.print the result.\n");
   int ch;
   scanf("%d",&ch);
   if(ch==2){break;}

   printf("Enter the date: (0/0/0 to cancel)\n ");
   scanf("%d/%d/%d", &day, &month, &year);
   if(fyear > year)
   {
       fyear = year;
       fmonth = month;
       fday = day;
   }
  else if ((fyear == year) && (fmonth > month))
   {
       fyear=year;
       fmonth=month;
       fday=day;
   }
   else
   {if ((fyear == year) && (fmonth == month) && (fday > day))
   {
       fyear=year;
       fmonth=month;
       fday=day;
   }
   }
}


 printf("Earliest Date is: %d/%d/%d\n",fday,fmonth,fyear);





    return 0;
}