明解C语言中级篇练习代码------第六章

这篇博客主要涵盖了C语言中级篇第六章的多个练习,包括6-1至6-7,详细讲解了每个练习的解题思路和代码实现。
摘要由CSDN通过智能技术生成

最近天天出去玩…
所以…
(´-﹏-`)

练习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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值