-1

私の大学のコースのこの C プログラムは、2 つの日付の間の日数を見つけることになっています。ほとんどの場合は機能しますが、通常、月 1 と月 2 が異なる場合、出力は数日だけ高くなります。また、月が 31 日であると認識されていないようで、日として「31」を入力すると「月と日の組み合わせが無効です」というエラー メッセージが表示されます。これらの問題のいずれかが発生している理由はまったくわかりません。助けてくれてありがとう!

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

4 に答える 4

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

true解析されるため、常に に評価されます

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

ゼロ以外の整数は に評価されtrueます。また、12月のことを忘れていました。

于 2012-04-24T00:06:08.677 に答える
0

あなたのコードにはこの構造がたくさんあります:

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

これは、C で行うと考えていることを行いません。次のように記述する必要があります。

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

これを修正してコードをクリーンアップした後、問題が解決しない場合は戻ってきます (ただし、新しい質問を作成してください)。

于 2012-04-24T00:06:18.560 に答える
0
i == 3||5||7||8||10||12

この条件は、異なるケースを区別するために使用できないためtrue、常に評価されます。||これは論理演算子であり、0 以外の値は に評価されtrueます。

日数を配列に格納することをお勧めします。

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

daysPerMonth[i]それほど複雑な条件を使わずに、月が何日あるかを簡単に知ることができるように. 可読性も向上します。

于 2012-04-24T00:08:16.903 に答える
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)

あなたのステートメントがすることは evaluate(month == 1) || 3です。このため3には、ブール値に変換する必要trueがあります。これは、ゼロではないため、 になることを意味します。そのため、比較の結果は true です。これは、if 節全体も true であることを意味します (実際のところ、怠惰とは、この時点で (または、月が実際に だった場合はそれよりも早く)、この権利を認識することを意味します1)、残りの月の数値を考慮しても何も計算しません。)

そのため、if 節全体が に評価されtrueます。コード内にこれらがたくさんあると、コードは奇妙なことをすることになります。

于 2012-04-24T00:11:36.167 に答える