我试图用C语言输出一个日历,我觉得我的格式有所下降,但我遇到了麻烦:
我目前的输出:
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");
}
答案 0 :(得分:2)
break
用于退出循环或切换语句。它只能在当前函数范围内的循环内使用。
因此,即使在getMonthYear()
(它不是)中的循环内调用main()
,其中的break
也不会退出该循环。
实际上,你在getMonthYear()
中都没有循环,也没有导致它的调用序列,所以break
将是一个无操作。
你必须问自己“当他们输入无效内容时我真正想做什么?”
一种可能性是从getMonthYear()
bool valid_input = 0;
while (!valid_input) {
valid_input = getMonthYear(&month, &year);
}
为了解决让一天变得正确的问题,你可能需要自己做一些调试:将print语句放在有计算的所有地方,打印中间结果,找出你的位置那样的错误。
答案 1 :(得分:1)
以下功能中存在错误:
toJulian
int toJulian(int month, int day, int year) {
int count;
for(count = 1; count < month; ++count) {
day += daysInMonth(month, year);
}
return day;
}
month
。您需要使用count
。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;
}
days
。year
而不是count
的参数中的leapYear
。以下是更新版本:
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" );
}
}
}
"%3d"
和" "
。您需要在第一个startDay
循环中为每天写入四个空格,直到for
。否则,第一行输出将无法正确对齐。您需要使用:
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
的界面。