最近天天出去玩…
所以…
(´-﹏-`)
练习6-1
//List 6-12的日历中,程序在横向排列的三个月的日历中间输出了3个空白字符。
//如果在右边月份后面没有输出空白字符,那么就能把3个月的日历控制在宽度为70位的控制台画面中。请编写并改良程序以达到此目的。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*--- 各月的天数 ---*/
int mday[12] = {
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
/*--- year年month月day日是星期几 ---*/
int dayofweek(int year, int month, int day)
{
if (month == 1 || month == 2) {
year--;
month += 12;
}
return (year + year/4 - year/100 + year/400 + (13*month+8)/5 + day) % 7;
}
/*--- year年是闰年吗?(0···平年/1···闰年) ---*/
int is_leap(int year)
{
return year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
}
/*--- year年month月的天数(28~31) ---*/
int monthdays(int year, int month)
{
if (month-- != 2)
return mday[month];
return mday[month] + is_leap(year);
}
/*--- 把y年m月的日历存入二维数组s中 ---*/
void make_calendar(int y, int m, char s[7][22])
{
int i, k;
int wd = dayofweek(y, m, 1);
int mdays = monthdays(y, m);
char tmp[4];
sprintf(s[0], "%10d / %02d ", y, m);
for (k = 1; k < 7; k++)
s[k][0] = '\0';
k = 1;
sprintf(s[k], "%*s", 3 * wd, "");
for (i = 1; i <= mdays; i++) {
sprintf(tmp, "%3d", i);
strcat(s[k], tmp);
if (++wd % 7 == 0)
k++;
}
if (wd % 7 == 0)
k--;
else {
for (wd %= 7; wd < 7; wd++)
strcat(s[k], " ");
}
while (++k < 7)
sprintf(s[k], "%21s", "");
}
/*--- 把存在三维数组sbuf中的日历横向排列n个并显示 ---*/
void print(char sbuf[3][7][22], int n)
{
int i, j;
for (i = 0; i < n-1; i++)
printf("%s ", sbuf[i][0]);
printf("%s", sbuf[i][0]); //将i<n的条件改为i<n-1,最后一个只输出字符串,不输出空格
putchar('\n');
for (i = 0; i < n-1; i++)
printf(" 日 一 二 三 四 五 六 ");
printf(" 日 一 二 三 四 五 六"); //同理,i=n时不输出空格
putchar('\n');
for (i = 0; i < n-1; i++)
printf("---------------------- "); //相同改动
printf("----------------------");
putchar('\n');
for (i = 1; i < 7; i++) {
for (j = 0; j < n-1; j++)
printf("%s ", sbuf[j][i]);
printf("%s", sbuf[j][i]); //相同改动
putchar('\n');
}
putchar('\n');
}
/*--- 显示自y1年m1月起至y2年m2月的日历 ---*/
void put_calendar(int y1, int m1, int y2, int m2)
{
int y = y1;
int m = m1;
int n = 0;
char sbuf[3][7][22];
while (y <= y2) {
if (y == y2 && m > m2) break;
make_calendar(y, m, sbuf[n++]);
if (n == 3) {
print(sbuf, n);
n = 0;
}
m++;
if (m == 13 && y < y2) {
y++;
m = 1;
}
}
if (n)
print(sbuf, n);
}
int main(void)
{
int y1, m1, y2, m2;
printf("显示日历。\n");
printf("输入开始年月。\n");
printf("年:"); scanf("%d", &y1);
printf("月:"); scanf("%d", &m1);
printf("输入结束年月。\n");
printf("年:"); scanf("%d", &y2);
printf("月:"); scanf("%d", &m2);
putchar('\n');
put_calendar(y1, m1, y2, m2);
return 0;
}
练习6-2
//List 6-12中没有检查开始年月和结束年月的一致性
//改良程序,使程序能够在检查一致性并发现错误后,提醒用户重新输入年月。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*--- 各月的天数 ---*/
int mday[12] = {
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
/*--- year年month月day日是星期几 ---*/
int dayofweek(int year, int month, int day)
{
if (month == 1 || month == 2) {
year--;
month += 12;
}
return (year + year/4 - year/100 + year/400 + (13*month+8)/5 + day) % 7;
}
/*--- year年是闰年吗?(0···平年/1···闰年) ---*/
int is_leap(int year)
{
return year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
}
/*--- year年month月的天数(28~31) ---*/
int monthdays(int year, int month)
{
if (month-- != 2)
return mday[month];
return mday[month] + is_leap(year);
}
/*--- 把y年m月的日历存入二维数组s中 ---*/
void make_calendar(int y, int m, char s[7][22])
{
int i, k;
int wd = dayofweek(y, m, 1);
int mdays = monthdays(y, m);
char tmp[4];
sprintf(s[0], "%10d / %02d ", y, m);
for (k = 1; k < 7; k++)
s[k][0] = '\0';
k = 1;
sprintf(s[k], "%*s", 3 * wd, "");
for (i = 1; i <= mdays; i++) {
sprintf(tmp, "%3d", i);
strcat(s[k], tmp);
if (++wd % 7 == 0)
k++;
}
if (wd % 7 == 0)
k--;
else {
for (wd %= 7; wd < 7; wd++)
strcat(s[k], " ");
}
while (++k < 7)
sprintf(s[k], "%21s", "");
}
/*--- 把存在三维数组sbuf中的日历横向排列n个并显示 ---*/
void print(char sbuf[3][7][22], int n)
{
int i, j;
for (i = 0; i < n-1; i++)
printf("%s ", sbuf[i][0