C Primer Plus (第六版) 第十四章_编程练习答案

no1.c

//重新编写复习题5,用月份名的拼写代替月份号(别忘了用strcmp()).在一个简单的程序中测试该函数
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
# include <ctype.h>

# define LEN 20

struct month
{
	char name[20] ; 
	char abbrev[4] ;
	int days ; 
	int monumb ;
};

long days(const struct month * months , int n , char * st);
char * s_get(char * st , int n);

int main(void)
{
	char st[LEN] ;
	struct month months[12] = 
	{
		"January" , "jan" , 31 , 1 ,
		"February" , "feb" , 28 , 2 ,
		"March" , "mar" , 31 , 3 ,
		"April" , "apr" , 30 , 4 ,
		"May" , "may" , 31 , 5 ,
		"June" , "jun" , 30 , 6 ,
		"July" , "jul" , 31 , 7 ,
		"August" , "aug" , 31 , 8 ,
		"September" , "sep" , 30 , 9 , 
		"October" , "oct" , 31 , 10 ,
		"November" , "nov" , 30 , 11 ,
		"December" , "dec" , 31 , 12 ,
	};
	int n = 0 ;

	puts("Enter a number(empty line to quit) :");
	while (s_get(st , LEN)&& st[0] != '\0')
	{
		printf("total days is %ld\n" , days(months ,12 , st));	
		puts("Enter a number(empty line to quit) :");
	}

	/*打印所有结构体内容
	for (int i = 0 ; i < 12 ; i++)
	{
		printf("No.%d\nmonth:%s\nabbrev:%s\ndays:%d\n",
				months[i].monumb,months[i].name ,
				months[i].abbrev,
				months[i].monumb);
	}
	*/

	return 0 ;
}

long days(const struct month * months , int n , char * st)
{
	long ret_val = 0 ;
	char * p_month ;
	char * p_str ;
	int find = 0 ;

	// 我这里使用了比较麻烦的模糊查找
	// 考虑的比较多,考虑到了用户输入不全的问题
	// 你们可以用题目提示的strcmp函数精确查找
	// 缺陷是只要一个字符不对,就认为不是
	for (int i = 0 ; i < n ; i++)
	{
		//动态分配空间,足够储存字符串
		p_month = (char *)calloc(sizeof(char) , strlen(months[i].name) + 1);
		p_str = (char *)calloc(sizeof(char) , strlen(st) + 1);

		//全部转换为小写
		for (int j = 0 ; j < sizeof(p_month); j++)
			p_month[j] =  tolower(months[i].name[j]) ;

		for (int j = 0 ; j < sizeof(p_str); j++)
			p_str[j] = tolower(st[j]);

		//字符串中寻找用户输入的字符串,找到后退出循环
		if (strstr(p_month , p_str))
		{
			find = i + 1 ;
			break ;
		}
	}

	if (find)
	{
		for (int i = 0 ; i < find ; i++)
			ret_val += months[i].days ;
	}

	return ret_val ; 
}

char * s_get(char * st , int n)
{
	char * ret_val ;
	char * find ;

	if (ret_val = fgets(st , n , stdin))
	{
		if (find = strchr(st , '\n'))
			*find = '\0' ;
		else 
			while (getchar() != '\n');
	}

	return ret_val ;
}

no2.c

//编写一个函数,提示用户输入日月年,月份可以是月份号,月份拼写,或月份名,
//然后该程序返回一年中到用户指定日子的总天数(包含这一天)
# include <stdio.h>
# include <string.h>
# include <ctype.h>

static struct 
{
	char number[10] ;	//月份号 按字符来
	char name[10]; 		//月份名
	char abb[10] ;		//月份缩写
	int days ;		//天数
}months[12] = 
{
	"1" , "january" , "jan" , 31 ,
	"2" , "february" ,"feb" , 28 ,
	"3" , "march" , "mar" ,31 ,
	"4" , "april" , "apr" ,30 ,
	"5" , "may" , "may" , 31 ,
	"6" , "june" , "jun" ,30 ,
	"7" , "july" , "jul" ,31 ,
	"8" , "august" , "aug" ,31 ,
	"9" , "september" , "sep" ,30 ,
	"10" , "october" , "oct" ,31 ,
	"11" , "novbemer" , "nov" ,30 ,
	"12" , "december" , "dec" ,31 ,
};

static struct
{
	int isleap ;
	int year ;
	int month ;
	int day;
}date;

void get_year(void);
void get_month(void);
void get_day(void);
int total_day(void);

int main(void) 
{
	int days ;
	char ch ;

	do{
		get_year();

		get_month();

		get_day();

		days = total_day();
		
		printf("%d年到第%d月%d日一共是%d天\n" , date.year , date.month , date.day , days);

		puts("继续吗?(y/n):");
		scanf("%c" ,&ch);
	}while (tolower(ch) == 'y');


	return 0 ;
}

void get_year(void)
{
	int y ; 

	puts("请输入年份:");
	while (scanf("%d" , &y) != 1 || y < 0)
	{
		while (getchar() != '\n') ;
		puts("输入错误,重新输入年份.");
	}

	while (getchar() != '\n') ;

	if (y % 4 == 0)
		if (y % 100 == 0 && y % 400 != 0)
			date.isleap = 0 ;
		else
			date.isleap = 1 ;
	else 
		date.isleap = 0 ;

	date.year = y ;
}

void get_month(void)
{
	char m[100] ;
	char * find ;
	int i = 0 ; 

	do{
		puts("请输入月份:");
 		if (fgets(m , 100 , stdin)) //这里将\n也读进来了
 		{
 			if (find = strchr(m , '\n')) 	//如果是完整的一行,就将读入的\n处理为\0
 				*find = '\0' ;
 			else 
 				while (getchar() != '\n') ;  //如果读入的是不完整的一行,将剩下的内容清理掉
 		}
		
		for (i = 0 ; i < 12 ; i++)
		{
			if (strcasecmp(months[i].number , m) == 0 || strcasecmp(months[i].name , m) == 0 ||
					strcasecmp(months[i].abb , m) == 0)
			{
				date.month = i + 1 ;
				break ;
			}
		}
		
		if (i >= 12)
		{
			while (getchar() != '\n') ;
			printf("输入错误,");
		}
	}while (i >= 12) ;

	//while (getchar() != '\n') ;  //<----如果有行,会出现再次输入的情况,原因是:前面的sgets已经将一行中剩下的清理了
				       //     这里本意为清理剩余输出,就变成了等待输入了.属于逻辑有错误
}

void get_day(void)
{
	int d ;
	int vaild  = 0 ;
	

	while (!vaild)
	{
		puts("请输入日子:");
		while (scanf("%d" , &d) != 1)
		{
			while (getchar() != '\n') ;
			puts("输入错误,清重新输入日子");
		}

		
		// months[month - 1].days + (isleap && month == 2)
		// 				0	0	0  不是闰年 , 不是2月份
		// 				0	1	0  不是闰年 , 是2月份
		// 				1	0	0  是闰年, 不是2月份
		// 				1	1	1  是闰年, 是2月份
		//

		if (d > (date.isleap && date.month == 2) + months[date.month - 1].days || d < 1)
		{
			puts("无效日期,请重新输入");
		}
		else 
			vaild = 1 ;
	}

	date.day = d ;

	while (getchar() != '\n') ; 
}

int total_day(void)
{
	int days = 0;

	for (int i = 0 ; i < date.month - 1 ; i++)
	{
		days += months[i].days ;
	}

	days += date.day ;

	if (date.isleap && date.month > 2)
		days++ ;

	return days ;
}

no3.c

//修改程序清单14.2中的图书目录程序,使其按照输入图书的顺序输出图书的的信息,
//然后按照标题的字母的声明输出信息,最后按照价格的升序输出图书的信息
# include <stdio.h>
# include <string.h>

# define MAXTITL 40 
# define MAXAUTL 40 
# define MAXBKS 100

char * s_gets(char * st , int n);

struct book
{
	char title[MAXTITL] ;	//书名
	char author[MAXAUTL] ;	//作者
	float value ;		//价格
};

int main(void)
{
	struct book library[MAXBKS] ;
	int count = 0 ; 
	int index ; 

	printf("Please enter the book title .\n");
	printf("Press [enter] at the start of line to stop .\n");
	while (count < MAXBKS && s_gets(library[count].title , MAXTITL) != NULL
			&& library[count].title[0] != '\0')
	{
		printf("Now enter the author.\n");
		s_gets(library[count].author , MAXAUTL);
		printf("Now enter the value.\n");
		scanf("%f" , &library[count++].value);
		while (getchar() != '\n') ;
		if (count < MAXBKS)
			printf("Enter the next title . \n");
	}

	if (count > 0)
	{
		printf("Here is the list of your books:\n");
		for (index = 0 ; index < count ; index++)
			printf("%s by %s : $%.2f\n" , library[index].title , library[index].author,
					library[index].value);

		//-------------------------------↓添加以下代码
		//按字符声明顺序(选择排序)
		for (int i = 0  , j = 0 ; i < count - 1 ; i++)
		{
			int min_index = i;
			for (j = i + 1 ; j < count ; j++)
				if (strcmp(library[min_index].title , library[j].title) > 0)
					min_index = j ;

			struct book tmp_book = library[i] ;
			library[i] = library[min_index] ;
			library[min_index] = tmp_book ;
		}

		puts("\n按字符声明排序如下");
		for (index = 0 ; index < count ; index++)
			printf("%s by %s : $%.2f\n" , library[index].title , library[index].author,
					library[index].value);
		
		//按价格顺序(冒泡排序)
		for (int i = 0 ; i < count - 1 ; i++)
		{
			for (int j = 0 ; j < count - 1 - i ; j++)
			{
				if (library[j].value > library[j + 1].value)
				{
					struct book tmp_book = library[j];
					library[j] = library[j + 1] ;
					library[j + 1] = tmp_book ;
				}
			}
		}
		puts("\n按价格.排序如下");
		for (index = 0 ; index < count ; index++)
			printf("%s by %s : $%.2f\n" , library[index].title , library[index].author,
					library[index].value);
		//-------------------------------↑
	}
	else
		printf("No books? Too bad.\n");

	return 0 ;
}

char * s_gets(char * st , int n)
{
	char * ret_val ;
	char * find ;

	ret_val = fgets(st , n , stdin);

	if (ret_val)
	{
		find = strchr(st , '\n');
		if (find)
			*find = '\0' ;
		else
			while (getchar() != '\n') ;
	}

	return ret_val ;
}

no4.c

//编写一个程序,创建一个有两个成员的结构模板
//a. 第1个成员是社会保险号,第2个成员是一个有3个成员的结构,第1个成员代表名,第2个成员代表中间名,第3个成员代表姓.
//   创建并初始化一个内含5个该类型结构的数组.该程序以下面的格式打印数据:
//   Dribble , Flossie M.  -- 302039823
//b. 修改a部分,传递结构的值而不是结构的地址.

# include <stdio.h>

# define LEN 20

struct person
{
	unsigned long long id ;

	struct 
	{
		char fname[LEN] ;
		char mname[LEN] ;
		char lname[LEN] ;
	};
};

void a_print(const struct person * pstc , int n);
void b_print(struct person ps);

int main(void)
{
	struct person shebao[5] = 
	{
		2374856963 , "yuan" , "li" , "D" ,
		2374856964 , "meng" , "qi" , "D" ,
		2374856965 , "zhu" , "ge" , "liang" , 
		2374856966 , "xia" , "hou" , "dun" ,
		2374856967 , "si" , "ma" , "gang"
	};
	
	printf("Part_A:\n"); 
	printf("--------------------------\n");
	a_print(shebao , 5);

	printf("\nPart_B:\n");
	printf("--------------------------\n");
	for (int i = 0 ; i < 5 ; i++)
		b_print(shebao[i]);

	return 0 ;
}

void a_print(const struct person * pstc , int n)
{
	for (int i = 0 ; i < n ; i++ , pstc++)
	{
		printf("%s , %s %s.\t  -- %llu\n",
				pstc->fname , pstc->lname , 
				pstc->mname , pstc->id);
	}
}

void b_print(struct person ps)
{
	printf("%s , %s %s.\t  -- %llu\n" , 
			ps.fname , ps.lname ,ps.mname , ps.id);
}

no5.c

//编写一个程序满足以下的要求.
//a. 外部定义一个有两个成员的结构模板 name :一个字符串储存名 , 一个字符串储存姓;
//b. 外部定义一个有3个成员的结构模板 student:一个name类型的结构,一个grade数组
//   储存3个浮点型分数,一个变量储存3个分数平均数.
//c. 在main()函数中声明一个内含CSIZE(CSIZE = 4)个student类型结构的数组,并初始化
//   这些结构的名字部分.用函数g,e,f和g中描述任务.
//d. 以交互的方式获取每个学生的成绩,提示用户输入学生的姓名和分数.把分数储存到
//   grade数组相应的结构中.可以在main()函
  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值