基于Win32控制台的万年历的实现(上)
2017-06-29 22:19
302 查看
本程序是基于Win32控制台的,当用户输入要显示日历的年份后,会显示该年的每一天所对应的星期,如图1所示。
![](https://img-blog.csdn.net/20170629221736615?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaG91MDl0aWFu/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
图1
万年历程序效果
![](https://img-blog.csdn.net/20170629221843399?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaG91MDl0aWFu/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
图1-1
万年历程序流程
int IsLeapYear(int year)
{
if ((year % 4 == 0) && (year % 100 !=
0) || year % 400 == 0)
return 366;
else
return 365;
}
int year;
printf("请输入要显示的年份:");
scanf_s("%d", &year);
int days_sum;
for (i = 1; i<y; i++)
days_sum += IsLeapyear(i);
int start_week;
start_week = (days_sum + 1) % 7;
其中,days_sum是在“2.1.1”中获取到的总天数,因为公元1年1月1日为星期一,即起点的值是1,所以需要对days_sum进行加1操作。
通过for循环实现指定年份12个月的遍历。
for (int i = 0; i<12; i = i + 1)
{
........
}
printf(" %d月 \n", i + 1);
其中,i的值是从0开始,而月份是从1开始,所以需要对i进行加1操作。
printf(" 日 一 二 三 四 五 六 \n");
printf("=============================\n");
for (int j = 0; j<start_week; j++)
printf(" ");
if (IsLeapYear(year) == 366)
days[1] = 29;
其中,year是要显示的年份,如果该年份是闰年,则将2月份的天数设置为29天。
while (day_month <= days[i])
{
printf("%4d", day_month);
day_month++;
}
其中,i是“2.2”中12个月的循环变量;用当前显示的天数day_month与相应月份的天数days[i]进行比较,如果显示的天数小于等于相应月份的天数,则说明当前月份的天数没有全部显示,则调用printf()函数进行显示。
start_week变量表示当前日期的星期数。因此,在“2.3.2”中的while()循环中,在显示了当前日期之后,接下来对start_week进行操作,判断当前星期是否全部显示。
start_week = (start_week + 1) % 7;
if (start_week == 0)
printf("\n");
start_week的值是0,则说明当前日期是星期天,此时就应该换行,开始显示下一个星期。
#include "stdafx.h"
#include <stdio.h>
int IsLeapYear(int year)
{
if ((year % 4 == 0) && (year % 100 != 0) || year % 400 == 0)
return 366;
else
return 365;
}
int main()
{
int year;
int i, j, days_sum = 0, t = 0;
int day_month, start_week;
int days[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
printf("请输入要显示的年份:");
scanf_s("%d", &year);
for (i = 1; i<year; i++)
days_sum += IsLeapYear(i);
start_week = (days_sum + 1) % 7;//表示该年1月1日为星期几
if (IsLeapYear(year) == 366)
days[1] = 29;
printf("\n%d年日历如下:\n\n", year);
for (i = 0; i<12; i = i + 1)
{
printf(" %d月 \n", i + 1);
printf(" 日 一 二 三 四 五 六 \n");
printf("=============================\n");
day_month = 1;
for (j = 0; j<start_week; j++)
printf(" ");
while (day_month <= days[i])
{
printf("%4d", day_month);
day_month++;
start_week = (start_week + 1) % 7;
if (start_week == 0)
printf("\n");
}
printf("\n\n");
}
return 0;
}
图1
万年历程序效果
1 流程图
万年历程序的流程图如1-1所示。图1-1
万年历程序流程
2 代码实现
2.1 确定要查询年份的1月1日
要实现指定年份中所有12个月份的显示,就必须要确定该年份的起始日期即1月1日是星期几。前提是公元1年1月1日为星期一,之后计算从公元1年1月1日起,到指定要查询年份的1月1日止,这个时间段中的天数,通过该天数得到查询年份的1月1日是星期几。2.1.1 获取时间段内的天数
(1)判断闰年
要获取时间段内的天数,就要判断这个时间段内哪些年份是闰年。通过一个自定义函数实现闰年的判断,该函数的参数是指定的年份,如果指定的年份是闰年,则函数的返回值是366,否则是365。int IsLeapYear(int year)
{
if ((year % 4 == 0) && (year % 100 !=
0) || year % 400 == 0)
return 366;
else
return 365;
}
(2)获取要显示的年份
通过scanf_s()函数获取输入的年份。int year;
printf("请输入要显示的年份:");
scanf_s("%d", &year);
(3)获取总天数
在获取了要显示的年份之后,循环调用IsLeapYear()函数对时间段内的年份包含的天数进行判断和累加,最后得到总天数。int days_sum;
for (i = 1; i<y; i++)
days_sum += IsLeapyear(i);
2.1.2 判断指定年份的1月1日是星期几
在获取了时间段内的总天数之后,用该天数与7(一个星期包含7天)进行取余运算,即可得到1月1日是星期几。假设星期天的值是0,星期一的值是1,依次类推:int start_week;
start_week = (days_sum + 1) % 7;
其中,days_sum是在“2.1.1”中获取到的总天数,因为公元1年1月1日为星期一,即起点的值是1,所以需要对days_sum进行加1操作。
2.2 循环显示日历标题、星期列表及1号前的空格
从图1中可以看到,显示每个月份的日期时,需要显示当前月份的名字以及星期的列表;如果当前月份的1号不是星期天,则还需要在其前面显示空格。通过for循环实现指定年份12个月的遍历。
for (int i = 0; i<12; i = i + 1)
{
........
}
2.2.1 显示日历标题
在for循环内部,i的值即为要显示的月份数。因此,通过以下代码显示日历标题,即月份数:printf(" %d月 \n", i + 1);
其中,i的值是从0开始,而月份是从1开始,所以需要对i进行加1操作。
2.2.2 显示星期列表
通过printf()函数输出字符串即可实现星期列表的显示。printf(" 日 一 二 三 四 五 六 \n");
printf("=============================\n");
2.2.3 显示1号前面的空格
在“2.1.2”中提到,start_week变量表示每个月的1号是星期几,而日历是从星期天开始显示的,星期天的值是0。所以,每个月的1号是星期几,则在1号前面就显示几个空格。for (int j = 0; j<start_week; j++)
printf(" ");
2.3 显示日期
首先定义一个整形数组,该数组中包含12个元素,分别对应12个月包含的天数。之后,判断当前月份的天数是否已经全部显示,如果没有全部显示,则继续显示天数。2.3.1 定义月份天数数组
int days[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };if (IsLeapYear(year) == 366)
days[1] = 29;
其中,year是要显示的年份,如果该年份是闰年,则将2月份的天数设置为29天。
2.3.2 判断当前月份的天数是否已经全部显示
int day_month = 1;while (day_month <= days[i])
{
printf("%4d", day_month);
day_month++;
}
其中,i是“2.2”中12个月的循环变量;用当前显示的天数day_month与相应月份的天数days[i]进行比较,如果显示的天数小于等于相应月份的天数,则说明当前月份的天数没有全部显示,则调用printf()函数进行显示。
2.4 判断当前星期是否全部显示
在显示日历时,一个星期为一行。因此,还需要判断当前星期是否全部显示,如果全部显示,则换行后继续显示日期。start_week变量表示当前日期的星期数。因此,在“2.3.2”中的while()循环中,在显示了当前日期之后,接下来对start_week进行操作,判断当前星期是否全部显示。
start_week = (start_week + 1) % 7;
if (start_week == 0)
printf("\n");
start_week的值是0,则说明当前日期是星期天,此时就应该换行,开始显示下一个星期。
#include "stdafx.h"
#include <stdio.h>
int IsLeapYear(int year)
{
if ((year % 4 == 0) && (year % 100 != 0) || year % 400 == 0)
return 366;
else
return 365;
}
int main()
{
int year;
int i, j, days_sum = 0, t = 0;
int day_month, start_week;
int days[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
printf("请输入要显示的年份:");
scanf_s("%d", &year);
for (i = 1; i<year; i++)
days_sum += IsLeapYear(i);
start_week = (days_sum + 1) % 7;//表示该年1月1日为星期几
if (IsLeapYear(year) == 366)
days[1] = 29;
printf("\n%d年日历如下:\n\n", year);
for (i = 0; i<12; i = i + 1)
{
printf(" %d月 \n", i + 1);
printf(" 日 一 二 三 四 五 六 \n");
printf("=============================\n");
day_month = 1;
for (j = 0; j<start_week; j++)
printf(" ");
while (day_month <= days[i])
{
printf("%4d", day_month);
day_month++;
start_week = (start_week + 1) % 7;
if (start_week == 0)
printf("\n");
}
printf("\n\n");
}
return 0;
}
相关文章推荐
- 基于Win32控制台的万年历的实现(下)
- java 实现一个基于控制台的 扫雷 游戏
- Win32控制台程序的定时器实现
- 利用GDI+基于WIN32实现桌面雪花效果(一)
- 基于win32的socket编程及程序实现
- win32 窗口程序实现控制台信息跟踪 简单案例
- WIN32汇编实现基于API的ODBC编程
- C++实现基于控制台界面的吃豆子游戏
- 基于sqlite3实现的简单通讯录程序(控制台)
- 在win32控制台应用程序中实现定时器
- Win32控制台程序的定时器实现 多媒体定时器
- 基于控制台或Win32 API程序生成文件版本信息
- VC++ 基于Win32控制台应用程序的ADO连接SQL server数据库
- win32控制台程序中定时器的实现
- 一种实现Win32消息处理处理函数的新方法 - 基于Thunk实现的类成员消息处理函数
- 基于类Win32_NetworkAdapterConfiguration实现Windows的网络配置
- 基于sqlite3实现的简单通讯录程序(控制台)
- 【C++源码】基于Win32窗口编程实现的小动画
- java控制台实现的万年历
- C++基于控制台实现的贪吃蛇小游戏