no1.c

//重新编写复习题5,用月份名的拼写代替月份号(别忘了用strcmp()).在一个简单的程序中测试该函数
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
# include <ctype.h># define LEN 20struct 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 ;elsedate.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 100char * 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);//-------------------------------↑}elseprintf("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' ;elsewhile (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 20struct 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()函数或其他函数中循环来完成
//e. 计算每个结构的平均分 , 并把计算后的值赋给合适的成员.
//f. 打印每个结构的信息.
//g. 打印班级的平均分,即所有结构的数值成员的平均值.# include <stdio.h># define LEN 10
# define CSIZE 4struct name
{char sname[LEN] ;char name[LEN] ;
};struct student
{struct name st_name;float grade[3] ;float average ;
};void in_score(struct student * pstr);
float get_float(void);
void out_score(const struct student * pstr , int n);int main(void)
{struct student stu[CSIZE] = {[0].st_name.sname = "zhang" , "san" ,[1].st_name.sname = "li" , "si" ,[2].st_name.sname = "wang" ,"wu" ,[3].st_name.sname = "zhao" , "liu"};for (int i = 0 ; i < CSIZE ; i++)in_score(&stu[i]) ;out_score(stu , CSIZE);
}void in_score(struct student * pstr)
{static char * lession[] = {"语文" , "数学" ,"英语" };float sum = 0 ;int i ;for (i = 0 ; i < 3 ; i++){printf("请输入%s %s的%s成绩:" , pstr->st_name.sname ,pstr->st_name.name , lession[i]);pstr->grade[i] = get_float() ;sum += pstr->grade[i] ;}pstr->average = sum / i ;
}float get_float(void)
{float f = 0 ;while (scanf("%f" , &f) != 1 || f < 0 || f > 100){while (getchar() != '\n') ;puts("无效输入,请重新输入");}return f ;
}void out_score(const struct student * pstr , int n)
{float sum = 0 ;printf("%10s %-10s %10s %10s %10s %10s \n" ,"姓" ,"名" , "语文" , "数学" , "英语" , "平均");for (int i = 0 ; i < n ; i++){printf("%10s %-10s %10.1f %10.1f %10.1f %10.1f\n" ,pstr[i].st_name.sname , pstr[i].st_name.name ,pstr[i].grade[0] , pstr[i].grade[1] , pstr[i].grade[2],pstr[i].average) ;sum += pstr[i].average ;}printf("全班的平均成绩是:%.1f\n" , sum / n);
}

no6.c

//一个文本文件中保存着一个垒球队的信息.每行数据都是这样排列的: 4 Jessie Joybat 5 2 1 1
//第1项是球员号,为了方便起见,其范围是0-18.第2项是球员的名.第3项是球员的姓.名和姓,都是一个单词
//第4项是官方统计的球员上场次数.接着3项分别是击中数,走垒数和打点(RBI).文件可能包含多场比赛的
//数据.编写一个程序,把数据储存到一个结构数组中.该结构中的成员要分别表示球员名,姓,上场次数,击中
//数,走垒数,打点和安打率(稍后计算).可以使用球员号作为数组索引.该程序要读到文件结尾.并统计每一位
//球员的各项累计总和.
//世界棒球统计与之相关.例如,一次走垒和触垒中的失误不计入上场次数,但是可能产生一个RBI.但是该程序
//要做的是像下面描述的一样读取和处理数据文件,不会关心数据的实际含义.要实现这些功能,最简单的方法是
//把结构的内容都初始化为0,把文件中的数据读入临时变量中,然后将其加入相应的结构中,程序读完文件后,应
//计算每一位球员的安打率,并把计算结果储存到结构的相应成员中.计算安打率是用球员的累计击中数除以上
//场次数.这是一个浮点数计算.最后程序结合整个球队的统计数据,一行显示一位球员的累计数据.# include <stdio.h>
# include <stdlib.h># define LEN 10typedef struct
{int num ;          //球员号char fname[LEN] ;      //名char lname[LEN] ;        //姓int play_times ;     //上场次数int hit_times ;           //击中次数int walk_times ;      //走垒数int rbi ;          //打点float hit_rate ;        //安打率
}player;int main(void)
{FILE * fp ;player * pstr ;player tmp_player ;int count = 0 ;int flag  = 0 ;//打开文件if ((fp = fopen("no2.txt" , "r")) == NULL){puts("打开文件失败");exit(EXIT_FAILURE);}while (fscanf(fp , "%d %s %s %d %d %d %d\n" , &tmp_player.num ,tmp_player.fname , tmp_player.lname ,&tmp_player.play_times , &tmp_player.hit_times,&tmp_player.walk_times , &tmp_player.rbi) != EOF){flag = 0 ;//先找此队员for (int i = 0 ; i < count ; i++){if (pstr[i].num == tmp_player.num){flag = 1 ;pstr[i].play_times += tmp_player.play_times ;pstr[i].hit_times += tmp_player.hit_times ;pstr[i].walk_times += tmp_player.walk_times ;pstr[i].rbi += tmp_player.rbi ;pstr[i].hit_rate = (double)pstr[i].hit_times / (double)pstr[i].play_times ;}}//未找到,添加新队员的信息if (!flag){if (count == 0)pstr = (player *)malloc(sizeof(player) * ++count); elsepstr = (player *)realloc(pstr , sizeof(player) * ++count);pstr[count - 1] = tmp_player ;pstr[count - 1].hit_rate = (double)pstr[count - 1].hit_times / (double)pstr[count - 1].play_times ; }}//打印每个球员的统计结果for (int i = 0 ; i < count ; i++){printf("%-10d %-10s %-10d %-10d %-10d %-10d %-10.d %10.2f%%\n" , pstr[i].num ,pstr[i].fname ,pstr[i].lname ,pstr[i].play_times ,pstr[i].hit_times ,pstr[i].walk_times ,pstr[i].rbi ,pstr[i].hit_rate);}fclose(fp);     //关闭文件free(pstr);       //释放空间return 0 ;
}

no7.c

//修改程序清单14.14,从文件中读取每条记录并显示出来,允许用户删除记录或者修改记录内容.
//如果删除记录,把空出来的空间留给下一个要读入的记录.要修改现有的文件内容,必须用"r+b"
//模式,而且,必需更加注意定位文件指针,防止新加入的记录覆盖现有记录.最简单的方法是改动
//在内存中的所有数据,然后再把最后的信息写入文件.跟踪的一个方法是在book结构中添加一个
//成员表示是否该项目删除.
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <ctype.h>
# include <math.h>
# include <windows.h># define MAXTITL 40
# define MAXAUTL 40
# define MAXBKS 10struct book
{int    del_flag;char   title[MAXTITL] ;char    author[MAXAUTL] ;float  value ;
};char * s_gets(char * st , int n) ;
FILE * file_open(const char * st) ;
long fdisplay(FILE * fp);
int menu_choice(FILE * fp);
void out_menu(void);
int fappend(FILE * fp);
int fmodify(FILE * fp);
int fdelete(FILE * fp);
int refresh(FILE * fp);int main(void)
{struct book library[MAXBKS] ;int count = 0 ;int index , filecount ; FILE * pbooks ;int size = sizeof(struct book);/*将编程清单14.14中这一段独立为 file_open();//打开文件if ((pbooks = fopen("book.dat" , "a + b")) == NULL){fputs("Can't open book.dat file\n" , stderr);exit(EXIT_FAILURE);}*//* 将编程清单中14.14中这一段独立为 fdisplay()函数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 ;*/pbooks = file_open("r + b");while (menu_choice(pbooks)) ;/* 将程序清单14.14这一段独立为fappend()函数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') ;if (count < MAXBKS)puts("Enter the next title.");}if (count > 0){puts("Here is the list of your books:");for (index = 0 ; index < count ; index++)printf("%s by %s : $%.2f\n" , library[index].title ,library[index].author , library[index].value);fwrite(&library[filecount] , size , count - filecount , pbooks);}elseputs("No books? Too bad.\n");*/puts("Bye.\n");fclose(pbooks);return 0 ;
}char * s_gets(char * st , int n)
{char * ret_val = NULL ;char * find ;if (ret_val = fgets(st , n , stdin)){if (find = strchr(st , '\n'))*find = '\0' ;elsewhile (getchar() != '\n') ;}return ret_val ;
}FILE * file_open(const char * st)
{FILE * fp ;if ((fp = fopen("book.dat" , st)) == NULL)             //如果打开失败{if ((fp = fopen("book.dat" , "w+b")) == NULL)      //新建文件{fputs("打开文件失败\n" , stderr);exit(EXIT_FAILURE);}fclose(fp);if ((fp = fopen("book.dat" , "r+b")) == NULL)        //重新以读写方式打开{fputs("打开文件失败\n" , stderr);exit(EXIT_FAILURE);}}return fp ;
}int menu_choice(FILE * fp)
{int choice ;out_menu();for (int i = 0 ; !scanf("%d", &choice); i++){while (getchar() != '\n') ;puts("非法输入,请输入正确的选项");if ((i + 1) % 5 == 0)out_menu() ;}while (getchar() != '\n') ;switch (choice){case 1:fdisplay(fp);break ;case 2://修改fmodify(fp);break ;case 3://添加fappend(fp);break ;case 4://删除fdelete(fp);system("pause");break;case 5: //退出文件操作//退出操作,将刷新文本,所有删除操作都将生效refresh(fp);choice = 0 ;break ;default ://出错choice = -1 ;puts("无效选择");system("pause");break;}return choice ;
}void out_menu(void)
{ static char * menu[] = {"#################################","请选择您需要的操作:" ,"1) 查看        2)修改","3) 添加      4)删除","5) 退出" , "#################################"};system("cls");for(int i = 0 ; i < sizeof(menu) / sizeof(menu[0]) ; i++)puts(menu[i]);
}long fdisplay(FILE * fp)
{long count = 0 ;struct book tmp_book ;puts("==========================================");rewind(fp);while (fread(&tmp_book , sizeof(struct book), 1 , fp)){if (!tmp_book.del_flag){printf("%s by %s : $%.2f\n" , tmp_book.title ,tmp_book.author , tmp_book.value);count++ ;}}rewind(fp);puts("==========================================");system("pause");return count ;
}int fappend(FILE * fp)
{int state = 0 ;struct book tmp ;puts("请输入您要添加的书名:");puts("按[Enter]输入空行退出:");while (s_gets(tmp.title , MAXTITL) && tmp.title[0]){puts("请输入作者:");while (!s_gets(tmp.author , MAXAUTL))puts("输入非法,请重新输入作者");puts("请输入价格:");while (!scanf("%f" , &tmp.value) || tmp.value < 0){while (getchar() != '\n') ;puts("无效数值,请重新输入");}while (getchar() != '\n') ;tmp.del_flag = 0 ;           //初始化删除标志位为0 , 表示未删除fseek(fp , 0L , SEEK_END);      //文件指针定位到文件最后state = fwrite(&tmp , sizeof(struct book), 1 , fp);fflush(fp);puts("请输入下一本书名:");}rewind(fp);return state ;
}int fmodify(FILE * fp)
{const char * tip = "无需修改请按[Enter]输入空行进入下一项";int state = 0 ;struct book tmp ;char bookname[MAXTITL];char tmp_st[MAXTITL] ; float tmp_flt = 0 ; //得到用户想要修改的 书名 并找到指定书名  未找到则回复用户未找到 puts("请输入您想要修改的书名:");s_gets(bookname , MAXTITL);rewind(fp);while (state = fread(&tmp , sizeof(struct book) , 1 , fp)){if (strcmp(tmp.title , bookname) == 0)break ;}if (state){state = 0 ;    //初始化状态值;puts("===============================");printf("%s\n请输入新的书名,%s\n",tmp.title , tip);while (!s_gets(tmp_st ,MAXTITL))puts("非法输入");if (*tmp_st && strcmp(tmp.title , tmp_st) != 0)strcpy(tmp.title , tmp_st);strcpy(tmp_st , "");puts("===============================");printf("%s\n请输入新的作者,%s\n",tmp.author , tip);while (!s_gets(tmp_st , MAXTITL))puts("非法输入");if (*tmp_st && strcmp(tmp.author , tmp_st) != 0)strcpy(tmp.author , tmp_st);strcpy(tmp_st , "") ;puts("===============================");printf("$%.2f\n请输入新的价格,%s\n" , tmp.value , tip);while (!s_gets(tmp_st , MAXTITL) || (tmp_flt = atof(tmp_st)) < 0) printf("无效输入");if (tmp_flt > 0)tmp.value = tmp_flt ;strcpy(tmp_st , "");tmp.del_flag = 0 ;      //初始化删除标志位为0 ,表示未删除puts("===============================");printf("将修改为:\n书名:%s\n作者:%s\n价格:%.2f\n " , tmp.title , tmp.author , tmp.value);puts("-------------------------------");puts("确定修改吗?(y/n)");if (s_gets(tmp_st , MAXTITL) && tolower(tmp_st[0]) == 'y'){fseek(fp , -((long)sizeof(struct book)) , SEEK_CUR);state = fwrite(&tmp , sizeof(struct book) , 1 , fp);fflush(fp);}if (state){puts("===============================");puts("修改成功!\n任意键返回菜单页面");getchar();}}else {puts("===============================");puts("书名不存在,请检查输入.\n任意键返回菜单页面");getchar();}rewind(fp);return state ;
}int fdelete(FILE * fp)
{int state = 0 ;struct book tmp ;char tmp_st[MAXTITL] ;int find = 0 ;int count = 0;// 判断文件是否有内容 , 无内容则不能修改fseek(fp , 0L , SEEK_END);if (ftell(fp) == 0){puts("错误:文件内无内容");return 0 ;}rewind(fp);puts("请输入您要删除的书名");if (s_gets(tmp_st , MAXTITL)){rewind(fp);while (find = fread(&tmp , sizeof(struct book) , 1 , fp)){if (strcmp(tmp.title , tmp_st) == 0)      //如果找到了,就将删除标志位置1{tmp.del_flag = 1;            //删除标志位置1fseek(fp , -((long)sizeof(struct book)) , SEEK_CUR); //定位到此记录fwrite(&tmp , sizeof(struct book) , 1 , fp);  //覆盖此记录fflush(fp);              //刷新文件break ;}}if (find)puts("删除成功,返回菜单页面");elseputs("未找到该书籍,请确认书名,或者添加该书籍");rewind(fp);}else {puts("无效输入");state = 0 ;} return state ;
}int refresh(FILE * fp)
{FILE * fp_tmp ;struct book bk_tmp ;int state  = 0 ;if (!(fp_tmp = fopen("book.tmp" , "wb+"))){fputs("关闭文件失败" , stderr);exit(EXIT_FAILURE);}rewind(fp) ;while (fread(&bk_tmp , sizeof(struct book) , 1 , fp)){if (!bk_tmp.del_flag){if (!fwrite(&bk_tmp , sizeof(struct book) , 1 , fp_tmp)){fputs("写入文件失败" , stderr);exit(EXIT_FAILURE);}}}fclose(fp_tmp);fclose(fp);system("del book.dat");system("rename book.tmp book.dat");return state ;
}//由于no7.c代码结构混乱,语句冗长,可读性,与维护性较低,所以最终决定重构no7.c
//以下程序思路,基于内存操作,使用了函数指针等简洁,可读性,维护性较高的技巧
//执行原理,程序启动将读取指定文件内所有内容,将内容整个放在内存中,关闭文件.
//接下来的增删查改等操作都对内存操作,当程序结束时,将内存中的所有数据重新写入
//文件内.
//缺点是对内存开销较大...但是目前我还未想到更好的办法
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <windows.h># define MAXTITL 20          //最大书名长度
# define MAXAUTL 20         //最大作者名长度
# define FILENAME "book.dat"      //宏定义文件名
# define FLDWIDTH 15            //字段宽度(表格)// 声明书籍结构体
typedef struct
{char   title[MAXTITL] ;char    author[MAXAUTL] ;float  value ;
}book;//定义全局结构体
static struct
{long COUNT ;book * BOOKS ;
}LIBRARY;long load_file(char * file);
long refresh_file(char * file);
void print_hline(const char ch , int count);
void print_squared(const char * st , int fwidth);
char * s_gets(char * st , int n);void out_menu(void);
int menu_choice(void);
void menu_end(void);
void lib_out(void);         //查
void lib_modify(void);          //改
void lib_add(void);         //增
void lib_del(void);         //删
int abort_operation();          //放弃操作int main(void)
{char ch[20] ;load_file(FILENAME) ;system("cls");while (menu_choice()){system("pause");system("cls");}refresh_file(FILENAME);free(LIBRARY.BOOKS);return 0 ;
}long load_file(char * file)
{FILE * fp  ;long size = 0;long item = 0 ;if (!(fp = fopen(file , "rb")))                  //打开文件失败{if (!(fp = fopen(file , "wb")))             //创建新的文件{fputs("创建文件失败" , stderr);exit(1);}fclose(fp);if (!(fp = fopen(file , "rb")))              //关闭文件并以读方式重新打开{fputs("打开文件失败" , stderr);exit(1);}}fseek(fp , 0L , SEEK_END);             size = ftell(fp);LIBRARY.COUNT = size / sizeof(book) ;LIBRARY.BOOKS = (book *) calloc(LIBRARY.COUNT , sizeof(book)) ;    //分配内存rewind(fp);                           //文件指针重新定位到文件首item = fread(LIBRARY.BOOKS , sizeof(book) , LIBRARY.COUNT , fp);//读取文件fclose(fp);return item ;
}long refresh_file(char * file)
{FILE * fp ;long item = 0 ;if (!(fp = fopen(file , "wb"))){fputs("更新文件失败" , stderr);exit(2);}item = fwrite(LIBRARY.BOOKS , sizeof(book) , LIBRARY.COUNT , fp);fclose(fp);return item ;
}void print_squared(const char * st , int fwidth)
{printf("%-*c%s%*c" , (fwidth - strlen(st)) / 2 , '|' , st , (fwidth - strlen(st)) / 2 , '|');
}void print_hline(const char ch , int count)
{putchar(' ');while (--count)putchar(ch);putchar('\n');
}char * s_gets(char * st , int n)
{char * find ;if (fgets(st , n , stdin)){if (find = strchr(st , '\n'))*find = '\0' ;else while (getchar() != '\n') ;}return st ;
}int menu_choice(void)
{static const void (* menu[])(void) = {menu_end , lib_out , lib_modify , lib_add , lib_del};int cmd = 0 ;out_menu();while (!scanf(" %d" , &cmd) || cmd < 0 || cmd > 4){if ((cmd < 0) || (cmd > 4))fputs("无效选择,请输入正确的序号:\n" , stderr);elsefputs("非法输入\n" , stderr);while (getchar() != '\n') ;}while (getchar() != '\n') ;menu[cmd]();return cmd ;
}void out_menu(void)
{ static char * menu[] = {"#################################","请选择您需要的操作:" ,"1) 查看        2) 修改","3) 添加     4) 删除","0) 退出" , "#################################"};for(int i = 0 ; i < sizeof(menu) / sizeof(menu[0]) ; i++)puts(menu[i]);
}
void menu_end(void)
{puts("再见,祝您生活愉快!");
}void lib_out(void)
{static const char * label[] = {"书名" ,"作者" ,"价格"} ;char tmp[100] ;// 打印表头print_hline('=' , (sizeof(label) / sizeof(label[0])) * FLDWIDTH - 4);for (int i = 0 ; i < sizeof(label) / sizeof(label[0]) ; i++)print_squared(label[i] , FLDWIDTH);putchar('\n');print_hline('=' , (sizeof(label) / sizeof(label[0])) * FLDWIDTH - 4);// 打印数据for (int i = 0 ; i < LIBRARY.COUNT; i++){print_squared(LIBRARY.BOOKS[i].title , FLDWIDTH);print_squared(LIBRARY.BOOKS[i].author , FLDWIDTH);sprintf(tmp ,"%.1f" ,LIBRARY.BOOKS[i].value) ;print_squared(tmp , FLDWIDTH);putchar('\n');print_hline('-' , (sizeof(label) / sizeof(label[0])) * FLDWIDTH - 4);}
}void lib_modify(void)
{book tbook ;char tstr[100] ;char answer ;int i ;float tfloat = 0 ;if (!LIBRARY.COUNT){puts("书籍为空,不能修改");return ;}lib_out();puts("请输入您要修改的书名(输入空行退出):");while (s_gets(tstr , 100) && tstr[0]){for (i = 0 ; i < LIBRARY.COUNT ; i++)if (strcmp(LIBRARY.BOOKS[i].title , tstr) == 0)break; if (i > LIBRARY.COUNT - 1)             //未找到书名给出提示puts("您输入的书名不存在!");else                        {tbook = LIBRARY.BOOKS[i] ;printf("书名: %s\n无需修改请按[Enter]输入空行\n" , tbook.title);if (s_gets(tstr , 100) && tstr[0])strncpy(tbook.title , tstr , MAXTITL) ;printf("作者: %s\n无需修改请按[Enter]输入空行\n" , tbook.author);if (s_gets(tstr , 100) && tstr[0])strncpy(tbook.author , tstr , MAXAUTL);printf("价格: %.1f\n无需修改请按[Enter]输入空行\n" , tbook.value);while (!s_gets(tstr , 100) || !tstr[0] || (tfloat = atof(tstr)) <= 0){if (!tstr[0]){tfloat = tbook.value ;break ;}elseputs("输入价格无效,请重新输入");}tbook.value = tfloat ;puts("=============================================");printf("书名: %s\n作者: %s\n价格: %.1f\n" , tbook.title , tbook.author , tbook.value);puts("您确定要修改?(y/n)");if (scanf(" %c" , &answer) && 'y' == tolower(answer)){LIBRARY.BOOKS[i] = tbook ;puts("修改成功!");}while (getchar() != '\n') ;}puts("请输入您要修改的下一本书名(空行退出)");}
}void lib_add(void)
{book tbook = {.value = 0} ;char ch ;char tmp[100] ;float tfloat = 0 ;puts("请输入您要添加的书名(输入空行退出)");while (s_gets(tbook.title , MAXTITL) && !tbook.title[0])if (abort_operation())return ;elseputs("请输入您要添加的书名(输入空行退出)");puts("请输入该书的作者,或者出版社(输入空行退出)");while (s_gets(tbook.author , MAXAUTL) && !tbook.author[0])if (abort_operation())return ;elseputs("请输入该书的作者,或者出版社(输入空行退出)");puts("请输入该书的价格(输入空行退出)");while (!s_gets(tmp , 100) || !tmp[0] || (tfloat = atof(tmp)) <= 0){if (!tmp[0]){if (abort_operation())return ;elseputs("请输入该书的价格(输入空行退出)");}else puts("输入价格无效,请重新输入(输入空行退出)");}tbook.value = tfloat ;puts("================================");puts("以下是您要添加的书籍信息:");printf("书名: %s\n" , tbook.title);printf("作者: %s\n" , tbook.author);printf("价格: %.1f\n" , tbook.value);puts("确认添加吗?(y/n)");if(scanf(" %c" , &ch) && 'y' == tolower(ch)){/*if (!LIBRARY.COUNT)LIBRARY.BOOKS = (book *)calloc(++LIBRARY.COUNT , sizeof(book)) ;else*/LIBRARY.BOOKS = (book *)realloc(LIBRARY.BOOKS ,++LIBRARY.COUNT * sizeof(book)) ;LIBRARY.BOOKS[LIBRARY.COUNT - 1] = tbook ;}
}void lib_del(void)
{char tmp_title[MAXTITL] ;int i ;if (!LIBRARY.COUNT){puts("书籍为空,不能删除");return ;}lib_out();puts("请输入您要删除的书名(空行退出)");while (s_gets(tmp_title ,MAXTITL) && tmp_title[0]){//寻找相同的书名for (i = 0 ; i < LIBRARY.COUNT ; i++)if (strcmp(LIBRARY.BOOKS[i].title , tmp_title) == 0)break; if (i > LIBRARY.COUNT - 1)                //未找到书名给出提示puts("您输入的书名不存在!");else                        {for (int j = i ; j < LIBRARY.COUNT ; j++)LIBRARY.BOOKS[j] = LIBRARY.BOOKS[j + 1] ;LIBRARY.BOOKS = (book *)realloc(LIBRARY.BOOKS , --LIBRARY.COUNT * sizeof(book));puts("删除成功!");}puts("请输入您要删除的书名(空行退出)");}
}int abort_operation()
{int answer = 0 ;char ch ;puts("你确定要放弃本次操作,并返回菜单页面?(y/n)");if (scanf(" %c" , &ch) && 'y' == tolower(ch))answer = 1 ;elseanswer = 0 ;while (getchar() != '\n');return answer ;
}

no8.c

//巨人航空公司的机群由12个座位的飞机组成.它每天飞行一个航班.根据下面的要求,编写一个座位预定程序
//a. 该程序使用一个内含12个结构的数组.每个结构中包括:一个成员表示座位编号.一个成员表示座位是否
//   已经被预定,一个成员表示预定人名,一个成员表示预定人的姓.
//b. 该程序显示下面的菜单:
//  To choose a function enter its letter label:
//  a) Show number of empty seats
//  b) Show list of emppty 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).# include <stdio.h>
# include <ctype.h>
# include <windows.h># define NAME_LEN 50
# define SEAT_COUNT 12typedef struct
{int number ;int selected ;char name[NAME_LEN] ;char s_name[NAME_LEN];
}seat;int initialize_seat(seat * pstr , int n);
void print_menu(void);
char choice_menu(void);
int switch_menu(int choice , seat * pstr);
int empty_seat_count(const seat * pstr , int n);
int show_seat_list(const seat * pstr , int n);
int sort_seat_list(seat * pstr , int n);
int choice_seat(seat * pstr , int n);
int delte_seat(seat * pstr , int n);
char * s_gets(char * st , int n);int main(void)
{seat plane_seat[SEAT_COUNT] ;initialize_seat(plane_seat , SEAT_COUNT);         //初始化座位while (switch_menu(choice_menu() , plane_seat)) ;puts("Bye. See you next!");return 0 ;
}int initialize_seat(seat * pstr , int n)
{int i;for (i = 0 ; i < n ; i++){pstr[i].number = i + 1 ;pstr[i].selected = 0 ;pstr[i].name[0] = '\0' ;pstr[i].s_name[0] = '\0' ;}return (i == n ? i : 0) ;
}char choice_menu(void)
{char ch ;print_menu();while (!scanf(" %c" , &ch) || !isalpha(ch = tolower(ch))){while (getchar() != '\n') ;puts("输入非法,请重新输入");}while (getchar() != '\n') ;return ch ;
}void print_menu(void)
{static char * menu[] = {"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"};system("cls");for (int i = 0 ; i < sizeof(menu) / sizeof(menu[0]) ; i++)puts(menu[i]);
}int switch_menu(int choice , seat * pstr)
{switch (choice){case 'a' ://显示未预定的座位数量empty_seat_count(pstr , SEAT_COUNT);system("pause");return 1;case 'b' ://显示空的座位列表show_seat_list(pstr , SEAT_COUNT);system("pause");return 1 ;case 'c' ://按字母顺序显示座位列表sort_seat_list(pstr , SEAT_COUNT) ;system("pause");return 1 ;case 'd' ://为客户分配座位choice_seat(pstr , SEAT_COUNT);system("cls");show_seat_list(pstr , SEAT_COUNT);system("pause");return 1 ;case 'e' ://删除座位分配delte_seat(pstr , SEAT_COUNT);system("cls");show_seat_list(pstr , SEAT_COUNT);system("pause");return 1 ;case 'f' ://退出return 0 ;default ://错误选择puts("无效选择,请重新选择");system("pause");return 1 ;}
}int empty_seat_count(const seat * pstr , int n)
{int count = 0 ;for (int i = 0 ; i < n ; i++){if (pstr[i].selected == 0)count++ ;}printf("现在空座为还剩%d个\n" , count);return count ;
}int show_seat_list(const seat * pstr , int n)
{int i ;puts("当前座位信息:");/*for (i = 0 ; i < n ; i++){if (pstr[i].selected == 0)printf("座位号: %2d (空)\n" , pstr[i].number);}*/for (i = 0 ; i < n ; i++)printf("座位号: %-5d %-5s 名:%-20s 姓:%-20s\n" ,pstr[i].number ,pstr[i].selected ? "已预订" : "未预定" ,pstr[i].name ,pstr[i].s_name );return i ;
}int sort_seat_list(seat * pstr , int n)
{seat ** pstr_arr ;seat  * tmp ;int min ;pstr_arr = (seat **)calloc( n , sizeof(seat *));for (int i = 0 ; i < n ; i++)pstr_arr[i] = &pstr[i] ;for (int i = 0 ; i < n - 1; i++){/*for (int j = 0 ; j < n - 1 - i ; j++){if (strcmp(pstr_arr[j]->name , pstr_arr[j + 1]->name) < 0){tmp = pstr_arr[j] ;pstr_arr[j] = pstr_arr[j + 1] ;pstr_arr[j + 1] = tmp ;}}*////*min = i ;for (int j = i + 1 ; j < n ; j++) if (strcmp(pstr_arr[min]->name , pstr_arr[j]->name) > 0)min = j ;if (min != i){tmp = pstr_arr[i] ;pstr_arr[i] = pstr_arr[min] ;pstr_arr[min] = tmp ;}//*/}for (int i = 0 ; i < n ; i++)printf("座位号: %-5d %-5s 名:%-20s 姓:%-20s\n" ,pstr_arr[i]->number ,pstr_arr[i]->selected ? "已预订" : "未预定" ,pstr_arr[i]->name ,pstr_arr[i]->s_name );free(pstr_arr);}int choice_seat(seat * pstr , int n)
{seat tmp ;char ch ;int flag = 0;puts("请输入您要挑选的座位号:");while (!scanf(" %d" , &tmp.number) || tmp.number < 1 || tmp.number > n || (flag = pstr[tmp.number - 1].selected)){while (getchar() != '\n');if (flag){puts("此座位已被预定,请重新选择座位:");flag = 0 ;}elseputs("非法输入,请重新输入座位号:");}while (getchar() != '\n') ;tmp.selected = 1 ;           //锁定此座位puts("请输入您的名:");while (!s_gets(tmp.name , NAME_LEN))puts("非法输入,请重新输入您的名:");puts("请输入您的姓:");while (!s_gets(tmp.s_name , NAME_LEN)) puts("非法输入,请重新输入您的姓:");puts("======================================");printf("座位号: %d\n名:%s\n姓:%s\n" , tmp.number , tmp.name , tmp.s_name);puts("确认预约此座吗?(y/n):");while (!scanf(" %c" , &ch) || !isalpha(ch = tolower(ch))) ;if (ch == 'y'){pstr[tmp.number - 1] = tmp ;return 1 ; }elsereturn 0 ;
}int delte_seat(seat * pstr , int n)
{int num ;int flag  = 0;char ch ;puts("请输入您要删除的座位号:");while (!scanf(" %d" , &num) || num < 1 || num > n || (flag = !pstr[num - 1].selected)){while (getchar() != '\n');if (flag){puts("取消预约失败,此座位并未被预约");flag = 0 ;}elseputs("非法输入,请重新输入要取消预约的座位号:");}while (getchar() != '\n') ;puts("======================================");printf("座位号: %d\n名:%s\n姓:%s\n" , pstr[num - 1].number , pstr[num - 1].name , pstr[num - 1].s_name);puts("确认此座取消预约吗?(y/n):");while (!scanf(" %c" , &ch) || !isalpha(ch = tolower(ch))) ;if (ch == 'y'){pstr[num - 1].selected = 0 ;pstr[num - 1].name[0] = '\0' ;pstr[num - 1].s_name[0] = '\0' ;return 1 ; }elsereturn 0 ;
}char * s_gets(char * st , int n)
{char * ret_value = NULL ;char * find ;if (ret_value = fgets(st , n , stdin)){if (find = (strchr(st , '\n')))*find = '\0' ;else while (getchar() != '\n') ;}return ret_value ;
}

no9.c

//巨人航空公司(编程练习8)需要另一架飞机(容量相同),每天飞4班(航班102 , 311 ,444 , 519).把程序扩展为可以处理4个航班
//.用一个顶层菜单提供航班选择退出.选择一个特定航班,就会出现和编程练习8类似的菜单.但是该菜单需要添加一个新选项:确认
//座位分配.而且菜单中的退出是返回顶层菜单.每次显示都要指明当前正在处理的航班号.另外,座位分配显示要指明确认状态.
# include <stdio.h>
# include <ctype.h>
# include <windows.h># define FLIGHT_COUNT 4
# define SEAT_COUNT 12
# define NAME_LEN 50 typedef struct
{int number ;int selected ;char name[NAME_LEN] ;char s_name[NAME_LEN];
}seat;int initialize_airline(seat * pstr , int r , int c);
void print_menu(int n);
char choice_menu(int n);
int switch_menu(int choice , seat * pstr);
int empty_seat_count(const seat * pstr , int n);
int show_seat_list(const seat * pstr , int n);
int sort_seat_list(seat * pstr , int n);
int choice_seat(seat * pstr , int n);
int delte_seat(seat * pstr , int n);
char * s_gets(char * st , int n);
void print_flight(void);
char choice_flight(void);
int flight_switch(char ch);int main(void)
{seat airline[FLIGHT_COUNT][SEAT_COUNT] ;int num ;initialize_airline(*airline, FLIGHT_COUNT ,SEAT_COUNT);           //初始化座位/*for (int i = 0 ; i < FLIGHT_COUNT ; i++){for (int j = 0 ; j < SEAT_COUNT ; j++)printf("%d %d %s %s\n" , airline[i][j].number , airline[i][j].selected ,airline[i][j].name , airline[i][j].s_name);if ((i + 1 % 2) == 0)putchar('\n');}*/while (num = flight_switch(choice_flight())){if (num > 0)while (switch_menu(choice_menu(num - 1) , airline[num - 1])) ;}puts("再见,欢迎下次乘坐.祝您生活愉快");return 0 ;
}int initialize_airline(seat * pstr , int r , int c)
{int i ;int j ;for (i = 0 ; i < r ; i++){for (j = 0 ; j < c ; j++){(pstr + (i * c + j))->number = j + 1 ;(pstr + (i * c + j))->selected = 0 ;(pstr + (i * c + j))->name[0] = '\0' ;(pstr + (i * c + j))->s_name[0] = '\0' ;}}return ((i * j) == (r * c) ? (i * j) : 0) ;
}int flight_switch(char ch)
{switch (ch){case 'a' ://厦航102return 1 ;break ;case 'b' ://国航311return 2 ;break ;case 'c' ://马航444return 3 ;break ;case 'd' ://南航519return 4 ;break ;case 'e' ://退出return 0 ;break ;default ://错误puts("无效选择,请重新选择");system("pause");return -1 ;break ;}
}char choice_menu(int n)
{char ch ;print_menu(n);while (!scanf(" %c" , &ch) || !isalpha(ch)){while (getchar() != '\n') ;puts("输入非法,请重新输入");}while (getchar() != '\n') ;return tolower(ch) ;
}void print_menu(int n)
{static const char * menu[] = {"请选择所要执行的操作:","a) 显示剩余未预定的座位数","b) 显示座位列表","c) 按首字母排序显示座位列表","d) 预定座位","e) 取消预定座位","f) 返回上一级菜单"};static const char * flight[] = {"厦航102" ,"国航311" ,"马航444" ,"南航519" ,};system("cls");printf("您选择的是[%s]航班\n", flight[n]);puts("-------------------------------------------------");for (int i = 0 ; i < sizeof(menu) / sizeof(menu[0]) ; i++)puts(menu[i]);
}int switch_menu(int choice , seat * pstr)
{switch (choice){case 'a' ://显示未预定的座位数量empty_seat_count(pstr , SEAT_COUNT);system("pause");return 1;case 'b' ://显示空的座位列表show_seat_list(pstr , SEAT_COUNT);system("pause");return 1 ;case 'c' ://按字母顺序显示座位列表sort_seat_list(pstr , SEAT_COUNT) ;system("pause");return 1 ;case 'd' ://为客户分配座位choice_seat(pstr , SEAT_COUNT);system("cls");show_seat_list(pstr , SEAT_COUNT);system("pause");return 1 ;case 'e' ://删除座位分配delte_seat(pstr , SEAT_COUNT);system("cls");show_seat_list(pstr , SEAT_COUNT);system("pause");return 1 ;case 'f' ://退出return 0 ;default ://错误选择puts("无效选择,请重新选择");system("pause");return 1 ;}
}int empty_seat_count(const seat * pstr , int n)
{int count = 0 ;for (int i = 0 ; i < n ; i++){if (pstr[i].selected == 0)count++ ;}printf("现在空座为还剩%d个\n" , count);return count ;
}int show_seat_list(const seat * pstr , int n)
{int i ;puts("当前座位信息:");/*for (i = 0 ; i < n ; i++){if (pstr[i].selected == 0)printf("座位号: %2d (空)\n" , pstr[i].number);}*/for (i = 0 ; i < n ; i++)printf("座位号: %-5d %-5s 名:%-20s 姓:%-20s\n" ,pstr[i].number ,pstr[i].selected ? "已预订" : "未预定" ,pstr[i].name ,pstr[i].s_name );return i ;
}int sort_seat_list(seat * pstr , int n)
{seat ** pstr_arr ;seat  * tmp ;int min ;pstr_arr = (seat **)calloc( n , sizeof(seat *));for (int i = 0 ; i < n ; i++)pstr_arr[i] = &pstr[i] ;for (int i = 0 ; i < n - 1; i++){/*for (int j = 0 ; j < n - 1 - i ; j++){if (strcmp(pstr_arr[j]->name , pstr_arr[j + 1]->name) < 0){tmp = pstr_arr[j] ;pstr_arr[j] = pstr_arr[j + 1] ;pstr_arr[j + 1] = tmp ;}}*////*min = i ;for (int j = i + 1 ; j < n ; j++) if (strcmp(pstr_arr[min]->name , pstr_arr[j]->name) > 0)min = j ;if (min != i){tmp = pstr_arr[i] ;pstr_arr[i] = pstr_arr[min] ;pstr_arr[min] = tmp ;}//*/}for (int i = 0 ; i < n ; i++)printf("座位号: %-5d %-5s 名:%-20s 姓:%-20s\n" ,pstr_arr[i]->number ,pstr_arr[i]->selected ? "已预订" : "未预定" ,pstr_arr[i]->name ,pstr_arr[i]->s_name );free(pstr_arr);}int choice_seat(seat * pstr , int n)
{seat tmp ;char ch ;int flag = 0;puts("请输入您要挑选的座位号:");while (!scanf(" %d" , &tmp.number) || tmp.number < 1 || tmp.number > n || (flag = pstr[tmp.number - 1].selected)){while (getchar() != '\n');if (flag){puts("此座位已被预定,请重新选择座位:");flag = 0 ;}elseputs("非法输入,请重新输入座位号:");}while (getchar() != '\n') ;tmp.selected = 1 ;           //锁定此座位puts("请输入您的名:");while (!s_gets(tmp.name , NAME_LEN))puts("非法输入,请重新输入您的名:");puts("请输入您的姓:");while (!s_gets(tmp.s_name , NAME_LEN)) puts("非法输入,请重新输入您的姓:");puts("======================================");printf("座位号: %d\n名:%s\n姓:%s\n" , tmp.number , tmp.name , tmp.s_name);puts("确认预约此座吗?(y/n):");while (!scanf(" %c" , &ch) || !isalpha(ch = tolower(ch))) ;if (ch == 'y'){pstr[tmp.number - 1] = tmp ;return 1 ; }elsereturn 0 ;
}int delte_seat(seat * pstr , int n)
{int num ;int flag  = 0;char ch ;puts("请输入您要删除的座位号:(0 退出)");while (!scanf(" %d" , &num) || num < 1 || num > n || (flag = !pstr[num - 1].selected)){while (getchar() != '\n');if (flag){puts("取消预约失败,此座位并未被预约");flag = 0 ;}else if (num == 0)            //终止取消预约操作return 0 ;elseputs("非法输入,请重新输入要取消预约的座位号:");}while (getchar() != '\n') ;puts("======================================");printf("座位号: %d\n名:%s\n姓:%s\n" , pstr[num - 1].number , pstr[num - 1].name , pstr[num - 1].s_name);puts("确认此座取消预约吗?(y/n):");while (!scanf(" %c" , &ch) || !isalpha(ch = tolower(ch))) ;if (ch == 'y'){pstr[num - 1].selected = 0 ;pstr[num - 1].name[0] = '\0' ;pstr[num - 1].s_name[0] = '\0' ;return 1 ; }elsereturn 0 ;
}char * s_gets(char * st , int n)
{char * ret_value = NULL ;char * find ;if (ret_value = fgets(st , n , stdin)){if (find = (strchr(st , '\n')))*find = '\0' ;else while (getchar() != '\n') ;}return ret_value ;
}void print_flight(void)
{static const char * flight[] = {"请选择一驾航班:" ,"a) 厦航102" ,"b) 国航311" ,"c) 马航444" ,"d) 南航519" ,"e) 退出"};system("cls");for (int i = 0 ; i < sizeof(flight) / sizeof(flight[0]) ; i++){puts(flight[i]);}
}char choice_flight(void)
{int ch ;print_flight() ;while (!scanf(" %c" , &ch) || !isalpha(ch)){while (getchar() != '\n') ;puts("非法输入,请重新选择");}return tolower(ch) ;
}

no10.c

//编写一个程序,通过一个函数指针数组实现菜单.例如.选择菜单中的a,将激活由该数组第1个元素指向的函数# include <stdio.h>
# include <windows.h>
# include <math.h>void print_menu(void);
int choice_menu(void);
void calculation(int cmd);
double fun_add(double x , double y);
double fun_sub(double x , double y);
double fun_mul(double x , double y);
double fun_div (double x , double y);
double get_number(void);int main(void)
{int n ;while ((n = choice_menu())){calculation(n - 1);}return 0 ;
}int choice_menu(void)
{int num ;print_menu();for (int i = 0 ; !scanf(" %d", &num) || num < 1 || num > 5 ; i++){while (getchar() != '\n');if ((i + 1) % 10 == 0)print_menu();puts("无效输入,请输入整数");}while (getchar() != '\n') ;return (num == 5 ? 0 : num );
}
void print_menu(void)
{static const char * menu[] = {"======================================" ,"请选择您需要的功能:" ,"1 加         2 减" ,"3 乘            4 除" ,"5 退出" ,"======================================" };system("cls");for (int i = 0 ; i < sizeof(menu) / sizeof(menu[0]) ; i++)puts(menu[i]);
}void calculation(int cmd)
{double r  , n1 , n2  ;double (*f[4])(double x ,double y) = {fun_add , fun_sub , fun_mul , fun_div} ;puts("请输入您要计算的第一个数:");n1 = get_number();puts("请输入您要计算的第二个数:");n2 = get_number();printf("计算结果为: %.2lf\n" , f[cmd](n1 , n2));system("pause");
}double fun_add(double x , double y)
{double sum = 0  ;sum = x + y ;return sum ;
}double fun_sub(double x , double y)
{double results = 0; results = x - y ;return results ;
}double fun_mul(double x , double y)
{double results = 0 ;results = x * y ;return results ;
}double fun_div (double x , double y)
{double results = 0 ;if (y == 0){fputs("参数错误:除数不能为0\n" , stderr);}elseresults = x / y ;return results ;
}double get_number(void)
{double x = 0;while (!scanf(" %lf" , &x)){while (getchar() != '\n') ;puts("无效输入,请输入正确的数字");}while (getchar() != '\n') ;return x ;
}

no11.c

// 编写一个名为transform()的函数,接受4个参数:内含double类型数据的源数组名,内含double类型数据的目标数组名,
// 一个表示数组元素个数的int类型参数,函数名(或等价的函数指针).transform()函数应把指针函数应用于源数组的每
// 个元素,并把返回值储存在目标数组中.例如:
// transform(source , target , 100 , sin) ;
// 该声明会把target[0]设置为sin(source[0]),等等,共有100个元素.在一个程序中调用transform()4次,以测试函数.分
// 别使用math.h函数库中的两个函数以及自定义的两个函数座位参数.# include <stdio.h>
# include <windows.h>
# include <math.h>int transform(double * source , double * traget , int n , double (*pfun)(double x));
void print_results(const double * source , int n);int main(void)
{double source[4] = {1 , 2 , 3 , 4};double traget[4] = {0};transform(source , traget , 4 , sin);puts("source :");print_results(source , 4);puts("traget :");print_results(traget , 4);return 0 ;
}int transform(double * source , double * traget , int n , double (*pfun)(double x))
{int i = 0 ;for (i = 0 ; i < n ; i++)traget[i] = pfun(source[i]);return i ;
}void print_results(const double * source , int n)
{for (int i = 0 ; i < n ; i++){printf("%lf " , source[i]);}putchar('\n');
}

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

  1. 【c++ primer】第五版第十四章习题答案

    第十四章 重载运算与类型转换 练习14.1 在什么情况下重载的运算符与内置运算符有所区别?在什么情况下重载的运算符又与内置运算符一样? 解: 不同点: 重载操作符不保证操作数的求值顺序,例如对& ...

  2. c++primer plus第六版第十二章第一题

    //h文件 #pragma once class cow {char name[20];char*hobby;double weight; public:cow();cow(const char*m, ...

  3. C Primer Plus(第6版)第十四章复习题答案

    1.正确的关键字是struct,最后一条声明语句以及结构模板有花括号要有分号. 2.输出如下 6 1 22 Spiffo Road S p 3.struct month { char name[10] ...

  4. Web前端开发精品课HTML CSS JavaScript基础教程第十四章课后编程题答案

    编程题: 下面有一段代码,请在这段代码的基础上使用正确的选择器以及这两章学到的字体样式.文本样式来实现图14-13所示的效果. <!DOCTYPE html> <html> & ...

  5. C primer plus(第六版)第十一章源代码

    C primer plus(第六版)第十一章源代码 /* 11.1 */ #include<stdio.h> #define MSG "I am a symbolic strin ...

  6. 《汇编语言》王爽(第四版) 第十四章 检测点及实验14

    文章目录 目录 前言 一.检测点 1.检测点14.1 (1)检测点14.1.(1) (2)检测点14.1.(2) 2.检测点14.2 (1)实验任务 (2)实现代码 二.实验14 访问CMOS RAM ...

  7. Java基础学习——第十四章 网络编程

    Java基础学习--第十四章 网络编程 一.网络编程概述 计算机网络: 把分布在不同地理区域的计算机与专门的外部设备用通信线路互连成一个规模大.功能强的网络系统,从而使众多的计算机可以方便地互相传递信 ...

  8. 第二十四章 并发编程

    第二十四章 并发编程 爱丽丝:"但是我不想进入疯狂的人群中" 猫咪:"oh,你无能为力,我们都疯了,我疯了,你也疯了" 爱丽丝:"你怎么知道我疯了&q ...

  9. 系统架构师学习笔记_第十四章_连载

    第十四章  基于ODP的架构师实践 14.1  基于ODP的架构开发过程 系统架构 反映了功能在系统系统构件中的 分布.基础设施相关技术.架构设计模式 等,它包含了架构的 原则 和 方法.构件关系 与 ...

最新文章

  1. java中native的用法[转]
  2. 应对电信劫持强行插入广告的处理
  3. 查询url包含的字符串参数(js高程笔记)
  4. python进行气象数据分析_使用机器学习进行气象数据分析
  5. 析构函数的标量与矢量?
  6. 远端异步调用事件结果
  7. 第十届泰迪杯数据挖掘挑战赛A题害虫识别YOLOv5模型代码(已跑通,原创作品,持续更新)
  8. JavaScript零基础入门 1:JavaScript表格简介
  9. uart协议学习,从了解到入门,看这篇文章
  10. 技能提升----直流有刷电机控制方案之经典
  11. 反编译apktool
  12. 如何通过关键字和搜索结果分析用户需求
  13. 【论文笔记】Toward A Thousand Lights Decentralized Deep Reinforcement Learning for Large-Scale TSC...
  14. Android多窗口模式(分屏模式)
  15. springboot整合POI导出word(文字加图片)
  16. chrome去广告插件
  17. 用C#简单实现迷你理财工具
  18. python2exe_Python 使用Py2exe进行bin化
  19. unity2D横版游戏跳跃实时响应
  20. 创建学生成绩数据库的简单sql语句

热门文章

  1. Android 客户端Socket 与 Java服务端ServerSocket
  2. 4-20ma和0-5v模拟量无线传输点对点无线采集控制解决方案io开关量信号无线远程控制解决方案
  3. nginx限流防刷方案
  4. linux内核配置cpu相关,Linux内核配置
  5. 从零开始画自己的DAG作业依赖图(三)--节点连线简单版
  6. 欧派家居的财务费用也出现了较快速度的增长
  7. WORD表格合并单元格并居中对齐
  8. 一二线城市知名IT互联网公司名单,看看你身边
  9. 高中数学必修2试题:直线平面平行的判定及其性质
  10. MIT又出新玩法,利用AI可轻松分离视频中的乐器声音