2012-04-24 25 views
-1

我的大学课程的C程序应该是查找两个日期之间的天数。它在大多数情况下都能正常工作,但是当month1和month2不同时,输出通常只有几天太高。此外,有31天的月份似乎没有被识别,因此当“31”作为当天输入时导致“无效的月份和日期组合”错误消息。我完全不知道为什么会出现这些问题。在此先感谢您的帮助!两个日期之间的C程序日 - 输出稍微高一点?

// Calculates the number of calendar days between any two dates in history (beginning with 1/1/1). 

#include <stdio.h> 
#include <stdlib.h> 

void date(int *month1, int *day1, int *year1, int *month2, int *day2, int *year2); 
void leap(int year1, int year2, int *leap1, int *leap2); 

int main(void) 
{ 
    int month1, day1, year1, month2, day2, year2, leap1, leap2; 

    date(&month1, &day1, &year1, &month2, &day2, &year2); 
    leap(year1, year2, &leap1, &leap2); 

    if(year1 == year2) 
    { 
    int i, total = 0; 

    if(month1 == month2)       // Total days if month1 == month2 
    { 
     total = day2 - day1; 
     printf("There are %d days between the two dates.", total); 
    } 
    else 
    { 
     if(month1 == 1||3||5||7||8||10)   // Days remaining in first month 
     total = 31 - day1; 
     else if(month1 == 4||6||9||11) 
     total = 30 - day1; 
     else 
     { 
     if(leap1 == 1) 
      total = 29 - day1; 
     else 
      total = 28 - day1; 
     } 

     for(i = month1 + 1; i < month2; i++) // Days remaining between dates (excluding last month) 
     { 
     if(i == 3||5||7||8||10) 
      total += 31; 
     else if(i == 4||6||9||11) 
      total += 30; 
     else 
     { 
      if(leap1 == 1) 
      total += 29; 
      else 
      total += 28; 
     } 
     } 

     total += day2;       // Final sum of days between dates (including last month) 

     printf("There are %d days between the two dates.", total); 
    } 
    } 
    else             // If year1 != year2 ... 
    { 
    int i, total, century1 = ((year1/100) + 1) * 100, falseleap = 0; 

    if(month1 == 1||3||5||7||8||10||12)    // Days remaining in first month 
     total = 31 - day1; 
    else if(month1 == 4||6||9||11) 
     total = 30 - day1; 
    else 
    { 
     if(leap1 == 1) 
     total = 29 - day1; 
     else 
     total = 28 - day1; 
    } 

    for(i = month1 + 1; i <= 12; i++)    // Day remaining in first year 
    { 
     if(i == 3||5||7||8||10||12) 
     total += 31; 
     else if(i == 4||6||9||11) 
     total += 30; 
     else 
     { 
     if(leap1 == 1) 
      total += 29; 
     else 
      total += 28; 
     } 
    } 

    for(i = 1; i < month2; i++)      // Days remaining in final year (excluding last month) 
    { 
     if(i == 1||3||5||7||8||10) 
     total += 31; 
     else if(i == 4||6||9||11) 
     total += 30; 
     else 
     { 
     if(leap2 == 1) 
      total += 29; 
     else 
      total += 28; 
     } 
    } 

    int leapcount1 = year1/4;      // Leap years prior to and including first year 
    int leapcount2 = year2/4;      // Leap years prior to and NOT including final year 
    if(year2 % 4 == 0) 
     leapcount2 -= 1; 

    int leaptotal = leapcount2 - leapcount1;  // Leap years between dates 

    for(i = century1; i < year2; i += 100)   // "False" leap years (divisible by 100 but not 400) 
    { 
     if((i % 400) != 0) 
     falseleap += 1; 
    } 

    total += 365 * (year2 - year1 - 1) + day2 + leaptotal - falseleap;  // Final calculation 
    printf("There are %d days between the two dates.", total); 
    } 
    return 0; 
} 

void date(int *month1, int *day1, int *year1, int *month2, int *day2, int *year2) 
{ 
    for(;;)               // Infinite loop (exited upon valid input) 
    { 
    int fail = 0; 
    printf("Enter first date: "); 
    scanf("%d/%d/%d", month1, day1, year1); 
    if(*month1 < 1 || *month1 > 12) 
    { 
     printf("Invalid entry for month.\n"); 
     fail += 1; 
    } 
    if(*day1 < 1 || *day1 > 31) 
    { 
     printf("Invalid entry for day.\n"); 
     fail += 1; 
    } 
    if(*year1 < 1) 
    { 
     printf("Invalid entry for year.\n"); 
     fail += 1; 
    } 
    if((*month1 == 4||6||9||11) && *day1 > 30) 
    { 
     printf("Invalid month and day combination.\n"); 
     fail += 1; 
    } 
    if(*month1 == 2) 
    { 
     if(*year1 % 4 == 0) 
     { 
     if(*year1 % 100 == 0) 
     { 
      if(*year1 % 400 == 0 && *day1 > 29) 
      { 
      printf("Invalid month and day combination.\n"); 
      fail += 1; 
      } 
      if(*year1 % 400 != 0 && *day1 > 28) 
      { 
      printf("Invalid month and day combination.\n"); 
      fail += 1; 
      } 
     } 
     if(*year1 % 100 != 0 && *day1 > 29) 
     { 
      printf("Invalid month and day combination.\n"); 
      fail += 1; 
     } 
     } 
     if(*year1 % 4 != 0 && *day1 > 28) 
     { 
     printf("Invalid month and day combination.\n"); 
     fail += 1; 
     } 
    } 
    if(fail > 0) 
     continue; 
    else 
     break; 
    } 

    for(;;) 
    { 
    int fail = 0; 
    printf("Enter second date: "); 
    scanf("%d/%d/%d", month2, day2, year2); 
    if(*month2 < 1 || *month2 > 12) 
    { 
     printf("Invalid entry for month.\n"); 
     fail += 1; 
    } 
    if(*day2 < 1 || *day2 > 31) 
    { 
     printf("Invalid entry for day.\n"); 
     fail += 1; 
    } 
    if(*year2 < 1) 
    { 
     printf("Invalid entry for year.\n"); 
     fail += 1; 
    } 
    if((*month2 == 4||6||9||11) && *day2 > 30) 
    { 
     printf("Invalid month and day combination.\n"); 
     fail += 1; 
    } 
    if(*month2 == 2) 
    { 
     if(*year2 % 4 == 0) 
     { 
     if(*year2 % 100 == 0) 
     { 
      if(*year2 % 400 == 0 && *day2 > 29) 
      { 
      printf("Invalid month and day combination.\n"); 
      fail += 1; 
      } 
      if(*year2 % 400 != 0 && *day2 > 28) 
      { 
      printf("Invalid month and day combination.\n"); 
      fail += 1; 
      } 
     } 
     if(*year2 % 100 != 0 && *day2 > 29) 
     { 
      printf("Invalid month and day combination.\n"); 
      fail += 1; 
     } 
     } 
     if(*year2 % 4 != 0 && *day2 > 28) 
     { 
     printf("Invalid month and day combination.\n"); 
     fail += 1; 
     } 
    } 
    if(fail > 0) 
     continue; 
    else 
     break; 
    } 
} 

void leap(int year1, int year2, int *leap1, int *leap2)    // Determines if first and final years are leap years 
{ 
    if(year1 % 4 == 0) 
    { 
    if(year1 % 100 == 0) 
    { 
     if(year1 % 400 == 0) 
     *leap1 = 1; 
     else 
     *leap1 = 0; 
    } 
    else 
     *leap1 = 1; 
    } 
    else 
    *leap1 = 0; 

    if(year2 % 4 == 0) 
    { 
    if(year2 % 100 == 0) 
    { 
     if(year2 % 400 == 0) 
     *leap2 = 1; 
     else 
     *leap2 = 0; 
    } 
    else 
     *leap2 = 1; 
    } 
    else 
    *leap2 = 0; 
} 
+0

'如果(MONTH1 == 1 || 3 || 5 || 7 || 8 || 10)'在C,这不会做你认为它。 – 2012-04-24 00:04:54

+0

你必须自己检查每一个条件,即:'如果(月== 1 ||月== 3 || ...)'。另外...这是一个比你可能意识到的更难的问题。 – 2012-04-24 00:06:11

回答

1
if(month1 == 1||3||5||7||8||10) 

始终计算为true,因为它被解析

if ((month == 1) || 3 || 5 || 7 || 8 || 10) 

和任何非零整数的计算结果为true。另外,你忘了十二月。

0

你有这样的构造有很多在你的代码:

value == 1||3||5||7||8||10||12 

这不会做你认为它在C,你必须把它写这样的:

value == 1 || value == 3 || value == 5 || etc... 

后你已经解决了这个问题,并清理了你的代码,如果问题依然存在的话(尽管提出一个新问题)。

+0

那么......它*工程* ...只是不是如何OP会喜欢它:) – 2012-04-24 00:06:38

0
i == 3||5||7||8||10||12 

这个条件总是evaulate到true becaue ||不能用于不同的情况之间进行区分。这是一个逻辑运算符,任何不等于0的值都将计算为true

我建议你的天数存储在数组中:

int daysPerMonth[] = {31,28,31,30 .. }; 

所以,你可以很容易地知道一个月有多少天有做daysPerMonth[i]没有那么多复杂的条件。它也会提高可读性。

+0

非常感谢你的这个建议。该程序现在完美工作! – Andbrik 2012-04-24 03:42:16

0

此:

if (month1 == 1||3||5||7||8||10||12) 

并不完全做你所想它做什么。你的意思是:

if (month1 == 1 || month1 == 3 || month1 == 5 || 
    month1 == 7|| month1 == 8|| month1 == 10|| month1 == 12) 

你的声明的作用是评估(month == 1) || 3。为此,它需要将3转换为布尔值,这意味着它将变为true,因为它不是零。这样,比较的结果是真,这意味着整个if子句也为true(作为事实上,懒惰意味着它实现了在这一点上这一权利(或更早如果月份实际上是1)和它if子句计算结果为true甚至不计算任何考虑月份数字的其余部分。)

因此,整体。在你的代码中有很多这样的代码,你的代码必然会做一些奇怪的事情。

+0

'=='比'||'具有更高的优先级,所以你的回答是错误的。查看[Daniel Fischer的回答](http://stackoverflow.com/a/10290024/445517)了解真正发生的事情。 – CodesInChaos 2012-06-16 21:23:38

+0

@CodeInChaos你是对的。虽然你指出的答案更为正确,但我确实发现它缺乏解释,所以我将我的答案修改为正确,仍然像解释一样。 – Jasper 2012-06-18 13:41:04