C Primer Plus 第6版 编程练习 chapter 14

文章目录

  • 1. 第1题
    • 1.1 题目描述
    • 1.2 编程源码
    • 1.3 结果显示
  • 2. 第2题
    • 2.1 题目描述
    • 2.2 编程源码
    • 2.3 结果显示
  • 3. 第3题
    • 3.1 题目描述
    • 3.2 编程源码
    • 3.3 结果显示
  • 4. 第4题
    • 4.1 题目描述
    • 4.2 题目a
      • 4.2.1 编程源码
      • 4.2.2 结果显示
    • 4.3 题目b
      • 4.3.1 编程源码
      • 4.3.2 结果显示
  • 5. 第5题
    • 5.1 题目描述
    • 5.2 编程源码
    • 5.3 结果显示
  • 6. 第6题
    • 6.1 题目描述
    • 6.2 编程源码
    • 6.3 结果显示
  • 7. 第7题
    • 7.1 题目描述
    • 7.2 编程源码
    • 7.3 结果显示
  • 8. 第8题
    • 8.1 题目描述
    • 8.2 编程源码
    • 8.3 结果显示
  • 9. 第9题
    • 9.1 题目描述
    • 9.2 编程源码
    • 9.3 结果显示
  • 10. 第10题
    • 10.1 题目描述
    • 10.2 编程源码
    • 10.3 结果显示
  • 11. 第11题
    • 11.1 题目描述
    • 11.2 编程源码
    • 11.3 结果显示

1. 第1题

1.1 题目描述

重新编写复习题5,用月份名的拼写代替月份号(别忘了使用strcmp)。在一个简单的程序中测试该函数。

1.2 编程源码

#include
#include
#include
#include
struct mon{
	char name[5];
	int id;
	int day_num;
};

int main(int argc, char* argv[]){
	char mon[12][5] ={"Jan.","Feb.","Mar.","Apl.","May.","Jun.","Jul.","Aug.","Sep.","Oct.","Nov.","Dec."};
	int n[]={31,28,31,40,51,30,31,31,30,31,30,31};
	
	struct mon m[12];
	for(int i=0;i<12;++i){
		m[i].id = i+1;
		m[i].day_num = n[i];
		strcpy(m[i].name, mon[i]);
	}
	
	printf("请输入你的月份名:");
	char s[5];
	scanf("%s", s);

	int day = 0;
	
	for(int i=0;i<12;++i){
		if(strcmp(s,m[i].name) != 0) day+= m[i].day_num;
		else{
			day+= m[i].day_num;
			break;
		}
	}
	
	printf("共计%d天\n",day);
	
	return 0;
}

1.3 结果显示

结果显示


2. 第2题

2.1 题目描述

编写一个函数,提示用户输入日、月和年。月份可以是月份号、月份名或月份名缩写。然后返回一年中到用户指定日子(包括这一天的总天数)。

2.2 编程源码

#include
#include
#include
#include

int is_run(int year){
	if(year % 400 == 0 || (year%4==0 && year%100!=0))return 1;
	return 0;
}

int cal_days(int year, int mon, int day){
	int n[]={31,28,31,40,51,30,31,31,30,31,30,31};
	int day_num = 0;
	for(int i=0;i<mon;++i){
		day_num += n[i];
	}
	day_num+=day;
	
	if(mon>1 && is_run(year)) ++day_num;
	return day_num;
}

int main(int argc, char* argv[]){
	char mon_sx[12][5] ={"Jan.","Feb.","Mar.","Apr.","May.","Jun.","Jul.","Aug.","Sep.","Oct.","Nov.","Dec."};
	char mon_name[12][20] ={"January","February","March","April","May","June","July","August.","September.","October.","November","December"};

	int day,mon=-1,year;
	char mon_n[20];
	
	printf("请输入年份:");
	scanf("%d",&year);
	while(getchar()!='\n');
	
	printf("请输入月份号、月份名或月份名缩写:");
	if(scanf("%d", &mon) != 1){
		scanf("%s", mon_n);
	}
	while(getchar()!='\n');
	
	printf("请输入日期:");
	scanf("%d",&day);
	while(getchar()!='\n');
	
	if(mon == -1){
		int flag = 0;
		for(int i=0;i<12;++i){
			if(strcmp(mon_sx[i], mon_n) == 0){
				mon = i+1;
				flag = 1;
				break;
			}
		}
		if(!flag){
			for(int i=0;i<12;++i){
				if(strcmp(mon_name[i], mon_n) == 0){
					mon = i+1;
					flag = 1;
					break;
				}
			}
		}
	}
	
	printf("共计%d天\n",cal_days(year,mon-1,day));	
	
	return 0;
}

2.3 结果显示

C Primer Plus 第6版 编程练习 chapter 14_第1张图片


3. 第3题

3.1 题目描述

修改程序清单14.2中的图书程序目录,使其按照输入图书的顺序输出图书的信息,然后按照标题字母的声明输出图书的信息,最后按照价格的升序输出图书的信息。

3.2 编程源码

#include
#include
#include

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

struct book{
	char title[MAXTITL];
	char author[MAXAUTL];
	float value;
};

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;
}

void display(const struct book *tb, int len){
	for(int i=0;i<len;++i)
		printf("%s by %s: $%.2f\n", tb[i].title, tb[i].author,tb[i].value);
}

void displaybyName(const struct book * b, int len){
	const struct book *tb[len]; 
	for(int i=0;i<len;++i)tb[i] = b++; 
	
	const struct book *t;
	for(int i=0;i<len;++i){
		for(int j=i;j<len;++j){
			if(strcmp(tb[i]->title,tb[j]->title) > 0){
				t = tb[i];
				tb[i] = tb[j];
				tb[j] = t;
			}
		}
	}
	for(int i=0;i<len;++i)
		printf("%s by %s: $%.2f\n", tb[i]->title, tb[i]->author,tb[i]->value);
}

void displaybyPrice(const struct book * b, int len){
	const struct book *tb[len]; 
	for(int i=0;i<len;++i)tb[i] = b++; 
	
	const struct book *t;
	for(int i=0;i<len;++i){
		for(int j=i;j<len;++j){
			if(tb[i]->value > tb[j]->value){
				t = tb[i];
				tb[i] = tb[j];
				tb[j] = t;
			}
		}
	}
	for(int i=0;i<len;++i)
		printf("%s by %s: $%.2f\n", tb[i]->title, tb[i]->author,tb[i]->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 a 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);
	}else{
		printf("No books? Too bad.\n");
	}
	printf("原来顺序:\n");
	display(library, count);
	printf("标题顺序:\n");
	displaybyName(library, count);
	printf("价格顺序:\n");
	displaybyPrice(library, count);
	return 0;
}

3.3 结果显示

C Primer Plus 第6版 编程练习 chapter 14_第2张图片


4. 第4题

4.1 题目描述

编写一个程序,创建一个有两个成员的结构模板:
a. 第1个成员是社会保险号,第2个成员是一个有3个成员的结构,第1个成员代表名,第2个成员代表中间名,第3个成员表示姓。 创建并初始化一个内含5个该类型结构的数组。该程序以下面的格式打印数据:

Daribble, Flossie M. -- 302039823

如果有中间名,只打印它的第1个字母,后面加一个点(.);如果没有中间名,则不用打印点。编写一个程序进行打印,把结构数组传递给这个函数。
b. 修改a部分,传递结构的值而不是结构的地址。

4.2 题目a

4.2.1 编程源码

#include
#include
#include

#define MAX	40

struct people{
	char id[MAX];
	struct {
		char name[MAX];
		char mid[MAX];
		char family[MAX];
	} x;
};

int main(void){
	struct people p[5]={
		"1001",{"ming","","li"},
		"1002",{"liang","xiao","zhang"},
		"1003",{"wei","da","wang"},
		"1004",{"han","zi","li"},
		"1005",{"wei","","wang"},
	};
	
	for(int i=0;i<5;++i){
		if(p[i].x.mid[0] != '\0')printf("%s, %s, %c. -- %s\n", p[i].x.name,p[i].x.family,p[i].x.mid[0],p[i].id);
		else printf("%s, %s, -- %s\n", p[i].x.name,p[i].x.family,p[i].id);
		
	}		
	
	return 0;
}

4.2.2 结果显示

C Primer Plus 第6版 编程练习 chapter 14_第3张图片

4.3 题目b

4.3.1 编程源码

#include
#include
#include

#define MAX	40

struct fn{
		char name[MAX];
		char mid[MAX];
		char family[MAX];
};

struct people{
	char id[MAX];
	struct fn *pfn;
};

int main(void){
	struct fn name[] = {
		{"ming","","li"},
		{"liang","xiao","zhang"},
		{"wei","da","wang"},
		{"han","zi","li"},
		{"wei","","wang"}
	};
	struct people p[5]={
		{"1001"},
		{"1002"},
		{"1003"},
		{"1004"},
		{"1005"}
	};
	
	for(int i=0;i<5;++i){
		p[i].pfn = (name+i);
	}
	
	for(int i=0;i<5;++i){
		if(p[i].pfn->mid[0] != '\0')printf("%s, %s, %c. -- %s\n", p[i].pfn->name,p[i].pfn->family,p[i].pfn->mid[0],p[i].id);
		else printf("%s, %s, -- %s\n", p[i].pfn->name,p[i].pfn->family,p[i].id);
		
	}
		
	return 0;
}

4.3.2 结果显示

C Primer Plus 第6版 编程练习 chapter 14_第4张图片


5. 第5题

5.1 题目描述

编写一个程序满足下面的要求。
a. 外部定义一个有两个成员的结构模板name:一个字符串储存名,一个字符串储存姓。
b. 外部定义一个有3个成员的结构模板student:一个name类型的结构,一个grade数组储存3个浮点型分数,一个变量储存3个分数平均数。
c. 在main函数中声明一个内含CSZIE(CSIZE=4)个student类型结构的数组,并初始化这些结构的名字部分。用函数执行g、e、f和g中描述的任务
d. 以交互的方式获取每个学生的成绩,提示用户输入学生的姓名和分数。把分数储存储存到grade数组相应的结构中。可以在main函数或其他函数中用循环完成。
e. 计算每个结构的平均分,并在计算后的值赋给合适的成员。
f. 打印每个结构的信息
g. 打印班级的平均分,即所有结构的数值成员的平均值。

5.2 编程源码

#include
#include
#include

#define MAX		40
#define CSIZE	4

struct name{
		char name[MAX];
		char family[MAX];
};

struct student{
	struct name n;
	float grade[3];
	float grade_avg;
};

void get_avg(struct student *s, int len){
	for(int i=0;i<len;++i)
		s[i].grade_avg = (s[i].grade[0]+s[i].grade[1]+s[i].grade[2])/3.0;
}

void display(const struct student *s, int len){
	for(int i=0;i<len;++i)
		printf("%s %s: %.2f %.2f %.2f %.2f\n",s[i].n.family,s[i].n.name, s[i].grade[0], s[i].grade[1], s[i].grade[2], s[i].grade_avg);

}

float get_total_avg(const struct student *s, int len){
	float sum = 0;
	for(int i=0;i<len;++i){
		for(int j=0;j<3;++j)
			sum += s[i].grade[j];
	}
	return sum/len/3;
}

int main(void){
	struct student s[CSIZE];
	
	for(int i=0;i<CSIZE;++i){
		printf("请输入你的姓名:");
		scanf("%s %s", s[i].n.family,s[i].n.name);
		while(getchar()!='\n');
		printf("\n请输入你的分数:");
		scanf("%f %f %f", s[i].grade, s[i].grade+1, s[i].grade+2);
		while(getchar()!='\n');
	}	

	get_avg(s,CSIZE);
	display(s,CSIZE);
	printf("总平均分为:%.2f\n", get_total_avg(s,CSIZE));
	
	return 0;
}

5.3 结果显示

C Primer Plus 第6版 编程练习 chapter 14_第5张图片


6. 第6题

6.1 题目描述

一个文本文件中保存着一个垒球队的信息。每行数据都是这样排列:

4 Jessie Joybar 5 2 1 1

第1项是球员号,为方便起见,其范围是0~18。第2项是球员的名,第3项是球员的姓。名和姓都是一个单词。第4项是官方统计的球员上场次数,接着3项分为是击中数、走垒数和打点(RBI)。文件可能包含多场比赛的数据,所以同一位球员可能有多行数据,而且同一位球员的多行数据之间可能有其他球员的数据。编写一个程序,把数据存储到一个结构数组中。该结构中的成员要分别表示球员的名、姓、上场次数、击中数、走垒数、打点和安打率(稍后计算)。可以使用球员号作为数组的索引。该程序要读到文件尾,并统计球员的各项累计总和。
世界棒球统计与之相关。例如,一次走垒和触垒中的失误不计入上场次数,但是可能产生一个RBI。但是该程序要做的是像下面描述的一样,读取和处理数据文件,不会关心数据的实际含义。
要实现这些功能,最简单的方法是把结构的初始化内容为0,把文件中的数据读入临时变量中,然后将其加入相应的结构中。计算安打率是用球员的累计击中数除以上场累计次数。这是一个浮点数计算。最后程序结合球队的统计数据,一行显示一位球员的累计数据。

6.2 编程源码

#include
#include
#include

#define MAX		40
#define SIZE	18

typedef unsigned int uint;

struct player{
	uint id;
	char name[MAX];
	char fam[MAX];
	
	uint attend_times;
	uint pick_times;
	uint zoulei_times;
	uint dadian_times;
	float anda;
	
};

int main(int argc, char **argv){
	if(argc<2){
		printf("请按照 程序 文件 的方式输入\n");
		exit(EXIT_FAILURE);
	}
	
	FILE *in;
	
	if((in=fopen(argv[1], "r"))==NULL){
		printf("%s 打开失败\n", argv[1]);
		exit(EXIT_FAILURE);
	}
	
	struct player s[SIZE]={0};
	int id,chang,jizhong,zoulei,dadian;
	char name[MAX],fal[MAX];
	
	while(fscanf(in, "%d",&id) == 1){
		fscanf(in, "%s %s %d %d %d %d",name,fal,&chang,&jizhong,&zoulei,&dadian);
		if(s[id].id == 0){
			strcpy(s[id].name, name);
			strcpy(s[id].fam, fal);
			s[id].id = id;
			s[id].attend_times = chang;
			s[id].pick_times = jizhong;
			s[id].zoulei_times = zoulei;
			s[id].dadian_times = dadian;
		}else{
			s[id].attend_times += chang;
			s[id].pick_times += jizhong;
			s[id].zoulei_times += zoulei;
			s[id].dadian_times += dadian;
		}
	}
	
	for(int i=0;i<SIZE;++i){
		if(s[i].id !=0){
			s[i].anda = s[i].pick_times/(float)s[i].attend_times;
		}
	}	

	for(int i=0;i<SIZE;++i){
		if(s[i].id !=0)
			printf("%d %s %s %d %d %d %d %f\n", s[i].id,s[i].name,s[i].fam,s[i].attend_times,s[i].pick_times,s[i].zoulei_times, s[i].dadian_times, s[i].anda);
	}
	
	fclose(in);
	
	return 0;
}

6.3 结果显示

a.txt

4 Jessie Joybar 5 2 1 1
3 da ming 5 2 1 1
2 xiao ming 5 2 2 2
4 Jessie Joybar 5 2 1 1

结果显示


7. 第7题

7.1 题目描述

修改程序清单14.14,从文件中读取每条记录并显示出来,允许用户删除记录或修改记录的内容。如果删除记录,把空出来的空间留给下一个要读入的记录。要修改现有的文件内容,必须用“r+b”模式,而不是“a+b”模式,而且,必须更加注意定位文件指针,防止新加入的记录覆盖现有记录。最简单的方法是改动储在内存中的所有数据,然后再把最后的信息写入文件。跟踪的一个方法是在book结构中添加一个成员表示是否该项被删除。

7.2 编程源码

#include
#include
#include

#define MAXTITL	40
#define	MAXAUTL	40
#define	MAXBKS	10

struct book{
	char title[MAXTITL];
	char author[MAXAUTL];
	float value;
	int is_deleted;
};

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;
}

int main(void){
	struct book library[MAXBKS];
	int count = 0;
	int index, filecount;
	FILE *pbooks;
	int size=sizeof(struct book);
	
	if((pbooks = fopen("book.dat", "r+b")) == NULL){
		fputs("Can`t open book.dat file\n", stderr);
		exit(1);
	}
	
	rewind(pbooks);
	while(count<MAXBKS && fread(&library[count], size,1,pbooks) == 1){
		if(count == 0) puts("Current contents of book.dat:");
		printf("%s by %s: $%.2f\n", library[count].title, library[count].author, library[count].value);
		++count;
	}
	filecount = count;
	if(count == MAXBKS){
		fputs("The book.dat file is full.", stderr);
		exit(2);
	}
	
	puts("Please add new book titles.");
	puts("Press [enter] at the start of a line to stop.");
	while(count<MAXBKS && s_gets(library[count].title, MAXTITL)!=NULL && library[count].title[0]!='\0'){
		puts("Now enter the author.");
		s_gets(library[count].author, MAXAUTL);
		puts("Now enter the value.");
		scanf("%f", &library[count++].value);
		while(getchar()!='\n')continue;
		if(count<MAXBKS)puts("Enter the next title.");
	}
	
	puts("Please deleted book titles.");
	puts("Press [enter] at the start of a line to stop.");
	char book_name[MAXTITL];
	while(s_gets(book_name, MAXTITL)!=NULL && book_name[0] != '\0'){
		for(int i=0;i<count;++i){
			if(strcmp(book_name,library[i].title) == 0)library[i].is_deleted = 1;
		}
		puts("Enter the next title.");
	}
	
	if(count>0){
		puts("Here is the list of your books:");
		for(index = 0;index<count;++index){
			if(library[index].is_deleted == 0){
				printf("%s by %s: $%.2f\n",library[index].title, library[index].author, library[index].value);
				fwrite(&library[index], size, 1, pbooks);
			}			
		}		
	}else puts("No books? Too bad.\n");
	
	puts("Bye.\n");
	fclose(pbooks);
	
	return 0;	
}

7.3 结果显示

C Primer Plus 第6版 编程练习 chapter 14_第6张图片


8. 第8题

8.1 题目描述

巨人航空公司的机群是由12个座位的飞机组成。它每天飞行一个航班。根据下面的要求,编写一个座位预定程序。
a. 该程序使用一个内含12个结构的数组。每个结构中包括:一个成员表示座位编号、一个成员表示座位是否已被预订、一个成员表示预订人的名、一个成员表示预订人的姓。
b. 该程序显示下面的菜单:

To choose a function , enter its letter label:
a) Show number of empty seats
b) Show list of empty seats
c) Show alphabetical list of seats
d) Assign a customer to a seat assignment
e) Delete a seat assignment
f) Quit

c. 该程序能成功执行上面给出的菜单。选择d)和e)要提示用户进行额外输入,每个选项都能让用户中止输入
d. 执行特定程序后,该程序再次显示菜单,除非用户选择f);

8.2 编程源码

#include
#include
#include

#define	MAXAUTL	40
#define	MAXTKTS	12

struct ticket{
	int id;
	int is_booked;
	char name[MAXAUTL];
	char family[MAXAUTL];
};

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;
}

void display_ui(){
	printf("To choose a function , enter its letter label:\n");
	printf("a) Show number of empty seats\n");
	printf("b) Show list of empty seats\n");
	printf("c) Show alphabetical list of seats\n");
	printf("d) Assign a customer to a seat assignment\n");
	printf("e) Delete a seat assignment\n");
	printf("f) Quit\n");
	printf("Enter [enter] to quit.\n");
}

void del_seats(struct ticket * t, int len){
	
	printf("请输入您要删除的号码:");
	int num;
	char n[MAXAUTL],f[MAXAUTL];
	while(scanf("%d", &num) == 1){
		while(getchar()!='\n');
		if(0<num && num <=len){
			if(t[num-1].is_booked == 0)printf("该号码无人预定,无需删除:");
			else {
				t[num-1].is_booked = 0;
				break;
			}
		}else{
			printf("请重新选择号码:");
		}		
	}		
}



void show_seats(const struct ticket * t, int len){
	puts("当前剩余座位号:");
	for(int i=0;i<len;++i){
		if(t[i].is_booked == 0)printf("%d\t",i+1);
	}
	putchar('\n');
}
void show_seat(const struct ticket * t, int len){
	puts("当前剩余座位号:");
	for(int i=0;i<len;++i){
		if(t[i].is_booked == 0){
			printf("%d\t",i+1);
			break;
		}
	}
	putchar('\n');
}

void show_seat_alp(const struct ticket * t, int len){
	const struct ticket *p[len];
	for(int i=0;i<len;++i)p[i]=t++;
	
	const struct ticket *tem;
	for(int i=0;i<len;++i){
		for(int j=i;j<len;++j){
			if(p[i]->is_booked && p[j]->is_booked && strcmp(p[i]->name, p[i]->name)>0){
				tem = p[i];
				p[i] = p[j];
				p[j] = tem;
			}
		}
	}
	
	for(int i=0;i<len;++i){
		if(p[i]->is_booked == 0)printf("%d\t%s %s\n",p[i]->id,p[i]->name, p[i]->family);
	}
	
}
void book_seats(struct ticket * t, int len){
	show_seats(t,len);
	printf("请选择您的号码:");
	int num;
	char n[MAXAUTL],f[MAXAUTL];
	while(scanf("%d", &num) == 1){
		while(getchar()!='\n');
		if(0<num && num <=len){
			if(t[num-1].is_booked)printf("该号码已有人选取,请重新选择号码:");
			else {
				t[num-1].id = num;
				printf("请输入您的姓名(中间使用空格隔开):");
				scanf("%s %s", n,f);
				strcpy(t[num-1].name,n);
				strcpy(t[num-1].family,f);
				t[num-1].is_booked = 1;
				break;
			}
		}else{
			printf("请重新选择号码:");
		}
		
	}
		
}

int main(void){
	struct ticket tickets[MAXTKTS]={0};
	
	display_ui();
	char c;
	
	while((c=getchar())!='\n'){
		switch(c){
			case 'a':show_seat(tickets, MAXTKTS);break;
			case 'b':show_seats(tickets,MAXTKTS);break;
			case 'c':show_seat_alp(tickets,MAXTKTS);break;
			case 'd':book_seats(tickets,MAXTKTS);break;
			case 'e':del_seats(tickets,MAXTKTS);break;
			case 'f':printf("Bye");exit(EXIT_SUCCESS);break;
			default:printf("please enter the character of the list.\n");
		}
		display_ui();
		while(getchar()!='\n');
	}
	
	return 0;	
}

8.3 结果显示

C Primer Plus 第6版 编程练习 chapter 14_第7张图片


9. 第9题

9.1 题目描述

巨人航空公司(编程练习8)需要另一架飞机(容量相同),每天飞4班(航班102、311、444和519)。把程序扩展为可用处理4个航班。用一个顶层菜单提供航班选择和退出。选择一个特定的航班,就会出现和编程练习8类似的菜单,但是该菜单要添加一个新选项:确认作为分配。而且,菜单中的退出是返回顶层菜单。每次显示都要指明当前正在处理的航班号,另外,座位分配显示要指明确认状态。

9.2 编程源码

#include
#include
#include

#define	MAXAUTL	40
#define	MAXTKTS	12

struct ticket{
	int id;
	int is_booked;
	char name[MAXAUTL];
	char family[MAXAUTL];
};

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;
}

void display_ui(){
	printf("To choose a function , enter its letter label:\n");
	printf("a) Show number of empty seats\n");
	printf("b) Show list of empty seats\n");
	printf("c) Show alphabetical list of seats\n");
	printf("d) Assign a customer to a seat assignment\n");
	printf("e) Delete a seat assignment\n");
	printf("f) Quit\n");
	printf("Enter [enter] to quit.\n");
}

void del_seats(struct ticket * t, int len){
	
	printf("请输入您要删除的号码:");
	int num;
	char n[MAXAUTL],f[MAXAUTL];
	while(scanf("%d", &num) == 1){
		while(getchar()!='\n');
		if(0<num && num <=len){
			if(t[num-1].is_booked == 0)printf("该号码无人预定,无需删除:");
			else {
				t[num-1].is_booked = 0;
				break;
			}
		}else{
			printf("请重新选择号码:");
		}		
	}		
}



void show_seats(const struct ticket * t, int len){
	puts("当前剩余座位号:");
	for(int i=0;i<len;++i){
		if(t[i].is_booked == 0)printf("%d\t",i+1);
	}
	putchar('\n');
}
void show_seat(const struct ticket * t, int len){
	puts("当前剩余座位号:");
	for(int i=0;i<len;++i){
		if(t[i].is_booked == 0){
			printf("%d\t",i+1);
			break;
		}
	}
	putchar('\n');
}

void show_seat_alp(const struct ticket * t, int len){
	const struct ticket *p[len];
	for(int i=0;i<len;++i)p[i]=t++;
	
	const struct ticket *tem;
	for(int i=0;i<len;++i){
		for(int j=i;j<len;++j){
			if(p[i]->is_booked && p[j]->is_booked && strcmp(p[i]->name, p[i]->name)>0){
				tem = p[i];
				p[i] = p[j];
				p[j] = tem;
			}
		}
	}
	
	for(int i=0;i<len;++i){
		if(p[i]->is_booked == 0)printf("%d\t%s %s\n",p[i]->id,p[i]->name, p[i]->family);
	}
	
}
void book_seats(struct ticket * t, int len){
	show_seats(t,len);
	printf("请选择您的号码:");
	int num;
	char n[MAXAUTL],f[MAXAUTL];
	while(scanf("%d", &num) == 1){
		while(getchar()!='\n');
		if(0<num && num <=len){
			if(t[num-1].is_booked)printf("该号码已有人选取,请重新选择号码:");
			else {
				t[num-1].id = num;
				printf("请输入您的姓名(中间使用空格隔开):");
				scanf("%s %s", n,f);
				strcpy(t[num-1].name,n);
				strcpy(t[num-1].family,f);
				t[num-1].is_booked = 1;
				break;
			}
		}else{
			printf("请重新选择号码:");
		}
		
	}
		
}

void display_flg(){
	printf("请选择航班:\n");
	printf("a)102\tb)311\tc)444\td)519\te)quit\n");
	printf("Enter [enter] to quit.\n");
}

int main(void){
	struct ticket tickets[MAXTKTS]={0};	
	char c;
	char f;
	int flight;
	int flag=0;
	
	display_flg();
	while((f=getchar())!='\n'){
		while(getchar()!='\n');
		flag = 0;
		switch(f){
			case 'a':flight=102;break;
			case 'b':flight=311;break;
			case 'c':flight=444;break;
			case 'd':flight=519;break;
			case 'e':printf("Bye");exit(EXIT_SUCCESS);break;
			default:flag=1;printf("please enter the character of the list.\n");
		}
		if(flag ==1)continue;		
		flag = 0;		
		display_ui();
		while((c=getchar())!='\n'){
			while(getchar()!='\n');
			flag = 0;
			printf("当前航班为%d\n", flight);
			switch(c){
				case 'a':show_seat(tickets, MAXTKTS);break;
				case 'b':show_seats(tickets,MAXTKTS);break;
				case 'c':show_seat_alp(tickets,MAXTKTS);break;
				case 'd':book_seats(tickets,MAXTKTS);break;
				case 'e':del_seats(tickets,MAXTKTS);break;
				case 'f':flag=2;break;
				default:printf("please enter the character of the list.\n");
			}
			if(flag == 2)break;			
			display_ui();			
		}
		display_flg();
	}	
	
	return 0;	
}

9.3 结果显示

C Primer Plus 第6版 编程练习 chapter 14_第8张图片


10. 第10题

10.1 题目描述

编写一个程序,通过一个函数指针数组实现菜单。例如,选择菜单中的a,将激活由该数组第1个元素指向的函数。

10.2 编程源码

#include

int add(int a,int b){
	return a+b;
}

int sub(int a,int b){
	return a-b;
}


int main(void){
	int (*f)(int a,int b);
	int a,b;
	
	printf("请输入两个数:\n");
	scanf("%d %d",&a,&b);
	while(getchar()!='\n');	
	
	printf("请选择菜单:\n");
	printf("a) add\tb)sub\n");
	
	char c;
	c = getchar();
	switch(c){
		case 'a':f=add;break;
		case 'b':f=sub;break;
		default: break;
	}
	printf("%d\n",f(a,b));
	
	return 0;	
}

10.3 结果显示

C Primer Plus 第6版 编程练习 chapter 14_第9张图片


11. 第11题

11.1 题目描述

编写一个名为tranaform的函数,接受4个参数:内含double类型数据的源数组名、内含double类型数据的目标数组名、一个表示数组元素个数的int类型参数、函数名(或等价的函数指针)。transform函数应把指定函数应用于源数组中的每个元素,并把返回值储存在目标数组中。例如:

transform(source, target, 100, sin);

该声明会把target[0]设置sin(source[0]),等等,共有100个元素。在一个程序中调用transform 4次,以测试该函数。分别使用math.h函数库中的两个以及自定义的两个函数作为参数。

11.2 编程源码

#include
#include

void transform(const double *s,double*t,int len, double (*f)(double a)){
	for(int i=0;i<len;++i)t[i] = f(s[i]);
}


int main(void){
	double s[]={1,2,3,4,5};
	double t[5];
	
	transform(s,t,5,sin);
	for(int i=0;i<5;++i) printf("%lf\t",t[i]);
	putchar('\n');
	
	return 0;	
}

11.3 结果显示

在这里插入图片描述


你可能感兴趣的:(C,Primer,Plus,第六版,编程练习,c语言,算法,开发语言)