当前位置: 首页 > 知识库问答 >
问题:

使用月份和年份输入在C中打印儒略日历?

方鸿羲
2023-03-14

我正在尝试用C语言输出日历,我想我已经把格式弄下来了,但我遇到了麻烦:

  1. 正在验证用户输入(我已经注释掉了潜在的解决方案,但它还没有正确编译。它总是打印“所选的年/月无效”,并且break语句不起作用。)
  2. 在一周的正确日期开始日历日(2018年5月从周二开始,而不是周日)

我目前的输出:

Enter month: 5
Enter year: 2018

 Su   M  Tu   W  Th   F  Sa
  1   2   3   4   5   6   7
  8   9  10  11  12  13  14
 15  16  17  18  19  20  21
 22  23  24  25  26  27  28
 29  30  31

我想要的输出:

Enter month: 5 
Enter year: 2018 

Su   M  Tu   W  Th   F  Sa
         1   2   3   4   5 
 6   7   8   9  10  11  12 
13  14  15  16  17  18  19 
20  21  22  23  24  25  26 
27  28  29  30  31 

这是我的程序:

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

/* #defines */
#define BEGIN 1900
#define DAYS_IN_WEEK 7

/* function prototypes */
void getMonthYear(int *month, int *year);
int toJulian(int month, int day, int year);
int daysInMonth(int month, int year);
int leapYear(int year);
long yearsToDays(int year);
void printCalendar(int startDay, int numDays);
void printHeader();

/* Calendar.c:  Prints monthly calendar.  Lab 4 / Week 9 */
void main(void)
{
    int month, year;
    int startDay;   // what day is first day of month.  1/1/1900 was Monday, so...
                    // day 1 is Mon, day 2 is Tue, ... , day 0 is Sun

    getMonthYear(&month, &year);
    startDay = (toJulian(month, 1, year) + yearsToDays(year)) % DAYS_IN_WEEK;
    printCalendar(startDay, daysInMonth(month, year));
}
void getMonthYear(int *month, int *year) {
    printf("Enter month: ");
    scanf("%d", month);
    /*if (month < 1 || month > 12) {
        printf("Invalid month selected");
        //break;
    }*/
    printf("Enter year: ");
    scanf("%d", year);
    /* if (year < BEGIN) {
        printf("Invalid year selected");
        //break;
    }*/
    printf("\n"); 
}
int toJulian(int month, int day, int year) {
    int count;
    for(count = 1; count < month; ++count) {
        day += daysInMonth(month, year);    
    }
    return day;
}
int daysInMonth(int month, int year) {
    int numDays;


switch (month) {
    case 1: numDays = 31;
        break;
    case 2: numDays = 28;
        break;
    case 3: numDays = 31;
        break;
    case 4: numDays = 30;
        break;
    case 5: numDays = 31;
        break;
    case 6: numDays = 30;
        break;
    case 7: numDays = 31;
        break;
    case 8: numDays = 31;
        break;
    case 9: numDays = 30;
        break;
    case 10: numDays = 31;
        break;
    case 11: numDays = 30;
        break;
    case 12: numDays = 31;
        break;
    }
    return numDays;
}
int leapYear(int year) {
    if (year % 400 == 0 && (year % 100 != 0 || year % 400 == 0)) {
        return 1;
    }
    else {
        return 0;
    }
}
long yearsToDays(int year) {
    int count;
    long days;
    for (count = BEGIN; count < year; ++count) {
        days = 365 + leapYear(year);
    }
    return days;
}
void printCalendar(int startDay, int numDays) {
    int dayid;
    printHeader();
    // Shifts position for the first date... sort of
        for ( dayid = 0; dayid < startDay; dayid++ ) {
            printf(" ");
        }

        // Supposedly prints all the dates for one month
        for ( dayid = 1; dayid <= numDays; dayid++ ) {
            printf("%3d", dayid );

            // If the day is not before Saturday, start next line on Sun
            if ( ( dayid + startDay ) % DAYS_IN_WEEK > 0 ) {
                printf(" ");
            }
            else {
                printf("\n" );
            }
        }
}
void printHeader() {
    printf(" Su   M  Tu   W  Th   F  Sa\n");
}

共有2个答案

易奇希
2023-03-14

以下函数中存在错误:

>

  • to Julian

    int toJulian(int month, int day, int year) {
        int count;
        for(count = 1; count < month; ++count) {
            day += daysInMonth(month, year);    
        }
        return day;
    }
    
    1. 您在每次通话中都使用月份。你需要使用count
    2. 您不需要输入参数day。可以在循环开始之前将局部变量初始化为0

    更新版本:

    int toJulian(int month, int year) {
        int count;
        int days = 0;
        for(count = 1; count < month; ++count) {
            days += daysInMonth(count, year);    
        }
        return days;
    }
    

    leapYear

    int leapYear(int year) {
        if (year % 400 == 0 && (year % 100 != 0 || year % 400 == 0)) {
            return 1;
        }
        else {
            return 0;
        }
    }
    

    if语句中的逻辑不正确。它需要是:

    (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0))
    

    通过使用以下命令,可以使函数更具可读性,更不容易出错:

    int leapYear(int year) {
       int ret = 0;
       if ( year % 4 != 0 )
       {
          ret = 0;
       }
       else 
       {
          if ( year % 100 != 0 )
          {
             ret = 1;
          }
          else 
          {
             ret = (year % 400 == 0);
          }
       }
    
       return ret;
    }
    

    yearsToDays

    long yearsToDays(int year) {
        int count;
        long days;
        for (count = BEGIN; count < year; ++count) {
            days = 365 + leapYear(year);
        }
        return days;
    }
    
    1. 您尚未初始化
    2. 你不是在累积天数。你只是在赋值。返回最后一个返回值,而不是累计天数
    3. 在循环中使用的是year,而不是leapYear的参数中的count

    以下是最新版本:

    long yearsToDays(int year) {
        int count;
        long days = 0;
        for (count = BEGIN; count < year; ++count) {
            days += 365;
            days += leapYear(count);
        }
        return days;
    }
    

    printCalendar

    void printCalendar(int startDay, int numDays) {
        int dayid;
        printHeader();
        // Shifts position for the first date... sort of
            for ( dayid = 0; dayid < startDay; dayid++ ) {
                printf(" ");
            }
    
            // Supposedly prints all the dates for one month
            for ( dayid = 1; dayid <= numDays; dayid++ ) {
                printf("%3d", dayid );
    
                // If the day is not before Saturday, start next line on Sun
                if ( ( dayid + startDay ) % DAYS_IN_WEEK > 0 ) {
                    printf(" ");
                }
                else {
                    printf("\n" );
                }
            }
    }
    
    1. 打印月份的天数时,您将使用四个空格-“=””。在第一个for循环中,您需要在startDay之前每天写四个空格。否则,第一行输出将无法正确对齐

    你需要使用:

            for ( dayid = 0; dayid < startDay; dayid++ ) {
                printf("    ");
            }
    

    main

    排队

    startDay = (toJulian(month, 1, year) + yearsToDays(year)) % DAYS_IN_WEEK;
    

    应该是

    startDay = (1 + toJulian(month, year) + yearsToDays(year)) % DAYS_IN_WEEK;
    

    为了解释(1)1900-Jan-01是星期一这一事实,(2)更改了toJulian的界面。

  • 宋宇
    2023-03-14

    break用于退出循环或开关语句。它只能在当前函数范围内的循环中使用。

    因此,即使在main()中的循环中调用了getMonthYear()(它不是),它内部的break也不会退出该循环。

    实际上,您根本没有循环,无论是在getMonthYear()中,还是在导致它的调用序列中,因此中断都是不可操作的。

    你必须扪心自问:“当他们输入无效条目时,我到底想做什么?”

    一种可能性是从getMonthial()返回有效性

    bool valid_input = 0;
    while (!valid_input) {
        valid_input = getMonthYear(&month, &year);
    }
    

    为了解决正确计算日期的问题,您可能需要自己多做一点调试:将print语句放在所有有计算的地方,打印出中间结果,并通过这种方式找出错误的地方。

     类似资料:
    • 问题内容: 我正在处理Java作业,它涉及在用户指定月份和年份之后打印日历。我不能使用Calendar或GregorianCalendar类。我的问题是日历在星期六的第一天无法正确打印月份。我已经看了大约一个小时的代码,但不确定出什么问题。我正在使用Zeller的Congruence查找以“ h”表示的每月的第一天。 例如,2008年3月的日历(错误地)如下所示: 这是我的代码: 问题答案: 从星

    • 我正在做一个Java作业,它涉及在用户指定月份和年份后打印日历。我不能使用日历或日历类。我的问题是日历不能正确地打印月份的第一天是星期六。我已经看了我的代码大约一个小时了,我不确定哪里出了问题。我用Zeller的同余来计算月的第一天,它由“h”表示。 例如,2008年3月的日历(错误)如下所示: 这是我的代码:

    • 问题内容: 我在python中有一个字符串。我需要将其转换为date对象,然后获取 year 以及 Julian day 的整数值。可能吗? 问题答案: 首先,您可以将其转换为这样的对象: 然后,您可以使用上的方法来获取所需的内容……除了没有直接所需的功能之外,因此您需要转换为时间元组 术语“朱利安日”具有几个不同的含义。如果要查找,则必须间接执行此操作,例如,以下一项。 如果您正在寻找不同的含义

    • 如果在程序中有人给我天数(ab=“days”),我需要将变量“days”设置为相同的数字(“val”中的值),如果有人给我月份(ab=“months”),那么我需要将其转换为天(val中的值),如果有人给我年(ab=“years”),那么我需要将其转换为天(val中的值)。ie如果用户在变量“ab”中指定了值的类型(即是月、年或日期)和变量“val”中的天数(天/月/年),我需要在变量“天”中获得

    • 问题内容: 如何在Java中动态显示for循环中特定月份的日期,月份和年份? 问题答案: 这简要演示了Java 和类的一些基础知识。根据您的问题,这是我能做的最好的事情。

    • 问题内容: 我正在尝试将包含2007年12月1日等各个部分的日期转换为SQL Server 2005中的日期时间。我尝试了以下方法: 但这会导致日期错误。将三个日期值转换为正确的日期时间格式的正确方法是什么? 问题答案: 假设全部,如何: