我正在尝试用C语言输出一个日历,我想我的格式已经缩小了,但我遇到了麻烦:
-
验证用户输入(I 've commented out the potential solution, but it hasn' t已正确编译 . 它始终打印"invalid year/month selected"并且break语句不起作用 . )
-
在一周的正确日期开始日历日(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 回答
您在以下函数中有错误:
toJulian
您在每次通话中都使用
month
. 你需要使用count
.您不需要输入参数
day
. 您可以在循环开始之前将局部变量初始化为0
.更新版本:
leapYear
.if
语句中的逻辑不正确 . 它需要是:使用以下命令可以使函数更易读,更不容易出错:
yearsToDays
您尚未初始化
days
.您没有累积天数 . 你只是分配一个值 . 返回最后返回的值而不是累计的天数 .
您在循环中使用
year
而不是leapYear
的参数中的count
.这是更新版本:
printCalendar
"%3d"
和" "
. 在第一个for
循环中,您需要为每天写入四个空格,直到startDay
. 否则,第一行输出将无法正确对齐 .你需要使用:
main
这条线
应该
考虑(1)1900-Jan-01属于星期一,(2)改为
toJulian
的界面 .break
用于退出循环或切换语句 . 它只能在当前函数范围内的循环内使用 .因此,即使
getMonthYear()
在main()
(它不是)中的循环内被调用,它内部的break
也不会退出该循环 .实际上,你根本没有循环,也没有
getMonthYear()
,也没有导致它的调用序列,所以break
将是一个无操作 .你必须问自己“当他们无效录入时我真正想做什么?”
一种可能性是从
getMonthYear()
返回有效性为了解决让一天变得正确的问题,您可能需要自己进行一些调试:将print语句放在有计算的所有位置,打印出中间结果,然后找出出错的地方 .