根据用户输入的日期打印日历(全年和一个月)时出现问题。加上计算 Zellers 同余的麻烦

Having issues printing out a calendar (both yearlong and month long) based on a date the user enters. Plus trouble with calculating Zellers Congruence

提问人:NattyTrill 提问时间:5/10/2023 更新时间:5/10/2023 访问量:45

问:

#include <ctype.h>
#include <math.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void printCalendarMonth();
void printCalendarYear();
int zellersCongruence();
void personalizedCalendar();
void firstCalendarMonth();
void perpetual();
void lunarPhase(); // declaring functions

enum month {
  January = 1,
  February,
  March,
  April,
  May,
  June,
  July,
  August,
  September,
  October,
  November,
  December // assigning a number with each month
};

int main() {
  int month[] = {};
  int z;
  int x;
  int y;
  int d;
  //The daycode of the first day of each month
  int daycode;
  enum month m; // declaring month day year and choice variables
  printf("\nEnter 1 to use a personalized calendar");
  printf("\nEnter 2 to print a past calendar or date");
  printf("\n\nEnter here: ");
  scanf("%i",
        &z); // select 1 for personalized calendar and 2 for everything else
  if (z == 1) {
    
    return (0);
  } else if (z == 2) {
    do {
      printf("Enter a year: ");
      scanf("%d", &y);
      if (y < 1582) {
        y = 0;
        printf("Year cannot be less than 1582!\n");
      }
    } while (y == 0); // asks for year and checks value

    if (y > 1582) { // if year is greater than 1582
      do {
        printf("\nSelect a month (1-12) of the year %i: ", y);
        scanf("%i", &m);
        switch (m) {
        case January:
          m = 1;
          break;
        case February:
          m = 2;
          break;
        case March:
          m = 3;
          break;
        case April:
          m = 4;
          break;
        case May:
          m = 5;
          break;
        case June:
          m = 6;
          break;
        case July:
          m = 7;
          break;
        case August:
          m = 8;
          break;
        case September:
          m = 9;
          break;
        case October:
          m = 10;
          break;
        case November:
          m = 11;
          break;
        case December:
          m = 12;
          break;
        default:
          printf("\nInvalid Month\n");
          m = 0;
        }
      } while (m == 0);
    } else if (y == 1582) { // if year entered is 1582
      do {
        printf("\nSelect a month (10-12) of the year 1582: ");
        scanf("%i", &m);
        switch (m) {
        case October:
          m = 10;
          break;
        case November:
          m = 11;
          break;
        case December:
          m = 12;
          break;
        default:
          printf("\nInvalid Month\n");
          m = 0;
        }
      } while (m == 0); // there are only 3 months on the gregorian calendar in
                        // the year 1582
    }
  }
  do {
    printf("Select a day in %d/%d: ", m, y);
    scanf("%i", &d);
    if (y == 1582 && m == 10 && (d >= 5 && d <= 14)) { // checks if day entered for october of 1582 is correct
      d = 0;
      printf("October 5th through 14th do not exist in October of 1852");
    } else if ((m == 1 || m == 3 || m == 5 || m == 7 || m == 8 || m == 10 || m == 12) && (d < 1 || d > 31)) { // checks months with 31 days
      d = 0;
      printf(
          "\nYour month has between 1 and 31 days.\nSelect a different day: ");
    } else if ((m == 4 || m == 6 || m == 9 || m == 11) && (d < 1 || d > 30)) { // checks months with 30 days
      d = 0;
      printf(
          "\nYour month has between 1 and 30 days.\nSelect a different day: ");
    } else if (m == 2 && ((y % 4 == 0 && y % 100 != 0) || y % 400 == 0) && (d < 1 || d > 29)) { // checks February on a leap year
      d = 0;
      printf("\nThis february is a leap year and thus has between 1 and 29 "
             "days.\nSelect a different day: ");
    } else if (m == 2 && (d < 1 || d > 28)) { // checks February on a non leap year
      d = 0;
      printf("\nThis february is not a leap year so it has between 1 and 28 "
             "days.\nSelect a different day: ");
    } else { // no other exceptions so date must b correct
      printf("\nThe date you've selected is: %d/%d/%d", m, d, y);
    }
  } while (d == 0);
  printf("\n\nWhat would you like to do with this date?");
  printf("\nEnter 1 to print the month calendar");
  printf("\nEnter 2 to print the year calendar");
  printf("\nEnter 3 to discover what day of the week %d/%d/%d is", m, d, y);
  printf("\nEnter 4 to discover what moon phase occured the day of %d/%d/%d", m,
         d, y); // menu options for date user has given
  do {
    printf("\n\nEnter choice here: ");
    scanf("%i", &z); // scans users choice
    switch (z) {
    case 1:
      printCalendarYear(); // calls print calendar year function
      break;
    case 2:
      printCalendarMonth(); // calls print calendar month function
      break;
    case 3:
      daycode = zellersCongruence(m, d, y); // calls zellers congruence function and uses variables given
      char day[10];
      switch (daycode) {
      case 0:
        strcpy(day, "Sunday");
        break;
      case 1:
        strcpy(day, "Monday");
        break;
      case 2:
        strcpy(day, "Tuesday");
        break;
      case 3:
        strcpy(day, "Wednesday");
        break;
      case 4:
        strcpy(day, "Thursday");
        break;
      case 5:
        strcpy(day, "Friday");
        break;
      case 6:
        strcpy(day, "Saturday");
        break;
      default:
        printf("Zeller's switch has failed!");
        break;
      }
      printf("The date you entered %d/%d/%d is a %s!", d, m, y, day);
      break;
    case 4:
      lunarPhase(); // calls lunar phase function
      break;
    default:
      z = 0;
      printf("Invalid choice made."); // must enter one of the choices above
    }
  } while (z == 0);
}

void printCalendarMonth(int mon[]) {
  printf(" Sun  Mon  Tue  Wed  Thu  Fri   Sat");
  // Fist Week in which the Month starts
  printf("\n| %2d |", mon[0]);
  printf(" %2d |", mon[1]);
  printf(" %2d |", mon[2]);
  printf(" %2d |", mon[3]);
  printf(" %2d |", mon[4]);
  printf(" %2d |", mon[5]);
  printf(" %2d |\n", mon[6]);
  printf("| %2d |", mon[7]);
  printf(" %2d |", mon[8]);
  printf(" %2d |", mon[9]);
  printf(" %2d |", mon[10]);
  printf(" %2d |", mon[11]);
  printf(" %2d |", mon[12]);
  printf(" %2d |\n", mon[13]);
  printf("| %2d |", mon[14]);
  printf(" %2d |", mon[15]);
  printf(" %2d |", mon[16]);
  printf(" %2d |", mon[17]);
  printf(" %2d |", mon[18]);
  printf(" %2d |", mon[19]);
  printf(" %2d |\n", mon[20]);
  printf("| %2d |", mon[21]);
  printf(" %2d |", mon[22]);
  printf(" %2d |", mon[23]);
  printf(" %2d |", mon[24]);
  printf(" %2d |", mon[25]);
  printf(" %2d |", mon[26]);
  printf(" %2d |\n", mon[27]);
  printf("| %2d |", mon[28]);
  printf(" %2d |", mon[29]);
  printf(" %2d |", mon[30]);
  printf(" %2d |", mon[31]);
  printf(" %2d |", mon[32]);
  printf(" %2d |", mon[33]);
  printf(" %2d |\n", mon[34]);
  printf("| %2d |", mon[35]);
  printf(" %2d |", mon[36]);
  printf(" %2d |", mon[37]);
  printf(" %2d |", mon[38]);
  printf(" %2d |", mon[39]);
  printf(" %2d |", mon[40]);
  printf(" %2d |\n", mon[41]);
}

// Function that create the arrays that will be used to print the individual
// months
void perpetual(int daycode) {
  int blank = 0;
  int i, k, m = 0;
  int month[] = {};
  do {
    month[i] = blank;
    ++i;
  } while (i < daycode);

  do {
    month[i + k] = k;
    ++k;
  } while (k < 31);
  month[i + k] = k;

  do {
    month[k + m] = blank;
    ++m;
  } while (m < 41);
}

// Funtion to call and print the frist month of the gregorian Calender: Oct,
// 1582
void firstCalendarMonth() {
  int Julian_Oct[] = {0,  1,  2,  3,  4,  15, 14, 15, 16, 17, 18, 19, 20, 21,
                      22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0,  0,  0,  0,
                      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0};
  printCalendarMonth(Julian_Oct);
}

void printCalendarYear(int year) {
  int i = 1;
  int h;
  int month[] = {};
  do {
    perpetual(zellersCongruence(1, i, year));
    printCalendarYear(month);
    ++i;
  } while (i <= 12);
}

void lunarPhase() {
  // References the user's inputs ofr month, year, day
  int m;
  int y;
  int d;
  // Initialzing variables that the function will use
  float julian_date;
  float days_since_new_moon;
  float phase;
  // Converting the int to float vaiables
  float day = d;
  float year = y;
  float month = m;
  if (m < 3) {
    year--;
    month += 12;
  }
  // Calculate the Julian date
  julian_date =
      floor(365.25 * year) + floor(30.59 * (month - 2)) + day + 1721088.5;

  // Calculate the number of days since the last new moon
  days_since_new_moon = julian_date - 2451549.5;

  // Calculate the current phase of the moon
  phase = fmod((days_since_new_moon / 29.53), 1.0);

  // Determine the phase of the moon
  if (phase < 0.03 || phase > 0.97) {
    printf("The moon is in the new moon phase\n");
  } else if (phase < 0.23) {
    printf("The moon is in the waxing crescent phase\n");
  } else if (phase < 0.27) {
    printf("The moon is in the first quarter phase\n");
  } else if (phase < 0.48) {
    printf("The moon is in the waxing gibbous phase\n");
  } else if (phase < 0.52) {
    printf("The moon is in the full moon phase\n");
  } else if (phase < 0.73) {
    printf("The moon is in the waning gibbous phase\n");
  } else if (phase < 0.77) {
    printf("The moon is in the last quarter phase\n");
  } else {
    printf("The moon is in the waning crescent phase\n");
  };
}

int zellersCongruence(int d, int m, int y) {
  int x;
  int k;
  int j;
  int h;
  if (m == 1) {
    m = 13;
    y--;
  }
  if (m == 2) {
    m = 14;
    y--;
  }
  x = (13 * (m + 1));
  h = d + (x / 5) + k + (k / 4) + (j / 4) - (2 * j);
  h = h % 7;
  return (h);
}

根据 Zeller 的一致性,它计算出 2023 年 5 月 8 日为星期日,而它应该是星期一。尝试打印日历会导致错误“信号分段故障(核心转储)”。尽管 Zeller 的 Congruence 不正确,但我们仍然试图根据错误的起点打印出日历。Zellers 是一个无效函数,但我们一直在尝试重新设计该程序,因此它已被更改。

C 函数 指针 数学 日历

评论

1赞 Harith 5/10/2023
int month[] = {};===> 你认为这有什么作用?
1赞 Retired Ninja 5/10/2023
此代码包含大量警告和错误。如果您没有看到警告,则需要调整编译器设置,并且需要注意它们。由于您没有指定您正在使用的输入,我猜崩溃是因为您没有将参数传递给需要参数的函数。godbolt.org/z/aYqboqTTc我的建议是从一个小的骨架程序开始,一次添加一个函数并测试它们,然后将其余的逻辑放在一起。
0赞 Harith 5/10/2023
更具体地说,需要一个 ,但你没有向它传递参数。printCalendarMonth()int array[]
0赞 Retired Ninja 5/10/2023
星期几计算可能会失败,因为公式中的两个变量和未初始化。jk
1赞 Jonathan Leffler 5/10/2023
在 中,你不会在使用它之前设置——这不是幸福的秘诀。zellersCongruence()j

答: 暂无答案