按输入字符月份和整数年份打印日历

时间:2017-12-11 18:53:04

标签: c calendar character

我已经编写了代码,通过输入整数月和整数年来打印一个月的日历。但是我想用字符输入月份,月份的前三个字母如1月和2月2月。如图所示,月份由字符输入。 Here is the Image。所以请更改代码,这样我就可以在字符中输入月份。谢谢

#include <stdio.h>

int isLeapYear(int y);        /* True if leap year */
int leapYears(int y);         /* The number of leap year */
int todayOf(int y, int m, int d); /* The number of days since the beginning
                                  of the year */
long days(int y, int m, int d);   /* Total number of days */
void calendar(int y, int m);       /* display calendar at m y */

int main(void) {
  int year, month;

  printf("Enter the month and year: ");
  scanf("%d %d", &month, &year);

  calendar(year, month);

  return 0;
}

int isLeapYear(int y) /* True if leap year */
{
  return(y % 400 == 0) || ((y % 4 == 0) && (y % 100 != 0));
}

int leapYears(int y) /* The number of leap year */
{
  return y / 4 - y / 100 + y / 400;
}

int todayOf(int y, int m, int d) /* The number of days since the beginning
                                 of the year */
{
  static int DayOfMonth[] =
  { -1/*dummy*/,0,31,59,90,120,151,181,212,243,273,304,334 };

  return DayOfMonth[m] + d + ((m>2 && isLeapYear(y)) ? 1 : 0);
}

long days(int y, int m, int d) /* Total number of days */
{
  int lastYear;

  lastYear = y - 1;

  return 365Q * lastYear + leapYears(lastYear) + todayOf(y, m, d);
}

void calendar(int y, int m) /* display calendar at m y */
{
  const char *NameOfMonth[] = { NULL/*dummp*/,
    "January", "February", "March", "April", "May", "June",
    "July", "August", "September", "October", "November", "December"
  };
  char Week[] = "Su Mo Tu We Th Fr Sa";
  int DayOfMonth[] =
  { -1/*dummy*/,31,28,31,30,31,30,31,31,30,31,30,31 };
  int weekOfTopDay;
  int i, day;

  weekOfTopDay = days(y, m, 1) % 7;
  if (isLeapYear(y))
    DayOfMonth[2] = 29;
  printf("\n     %s %d\n%s\n", NameOfMonth[m], y, Week);

  for (i = 0; i<weekOfTopDay; i++)
    printf("   ");
  for (i = weekOfTopDay, day = 1; day <= DayOfMonth[m]; i++, day++) {
    printf("%2d ", day);
    if (i % 7 == 6)
      printf("\n");
  }
  printf("\n");
}

1 个答案:

答案 0 :(得分:1)

有很多方法可以做到这一点。它们通常涉及获取输入字符串并查找某些表格。

一种有效的方法是根据字符串输入计算哈希,而不是最多12个字符串比较。使用哈希查看月份名称并查看它是否匹配。下面的哈希需要月份名称的ASCII编码。 char可能已签名或未签名。

当然如果月份名称改变(另一种语言?),下面的具体值和哈希方法需要调整。

// Assume month is any 3 ASCII characters (either case)
int month2int_chux(const char *month) {
  if (month[0] && month[1] && month[2]) {
    unsigned m0 = month[0] | 0x20;
    unsigned m1 = month[1] | 0x20;
    unsigned m2 = month[2] | 0x20;
    unsigned m = (14 * m2) ^ (47 * m1);  // magic computation does not use m0.
    m %= 13;
    const unsigned char hash[] = { 9, 11, 5, 12, 0, 7, 2, 1, 3, 4, 8, 10, 6 };
    m = hash[m % 13u];
    if (m && (NameOfMonth[m][0] | 0x20) == m0 &&  
        NameOfMonth[m][1] == m1 && NameOfMonth[m][2] == m2) {
      return m;
    }
  }
  return 0;
}