C Primer Plus第十四章编程练习,仅供参考

第十四章编程练习

第一个问题让我们改写复习题5,创建一个函数去计算一年到某个月份的天数,在一个结构数组中去存储相关数据。完整程序代码以及运行结果如下:

#include<stdio.h>
#include<string.h>
#include<ctype.h>
struct month
{
    char name[20];
    char abbr[4];
    int days;
    int number;
};
const 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 jiSuan(const char *);
int main(void){
    char input[20];
    int total;
    printf("请输入一个月份:\n");
    while (scanf("%s",input) == 1 && input[0] != 'q'){
        total = jiSuan(input);
        if (total>0){
            printf("到%s月为止,一共有%d天。\n",input,total);
        }else{
            printf("输入的月份可能存在错误,请检查。\n");
        }
        printf("请输入下一个月份。输入q结束循环\n");   
    }
    printf("Done!!!");
    return 0;
}
int jiSuan(const char * in){
    int n = 0;
    int r = 0;
    for (int i = 0; i < 12; i++){
        if(strcmp(in,months[i].name) == 0){
            n = months[i].number;
        }
    }
    for (int i = 0; i < n; i++){
        r += months[i].days;
    }
    return r;
}

在这里插入图片描述

接下来,我们来看一下第二题的要求,获取输入的日、月和年,月份可以是三种格式,然后返回一年中到指定日子的总天数。这里就有一个问题了,输入了年份,那么平闰年要处理吗,题目里并没有明确的说明。我们简单的对其处理一下,完整程序代码以及运行结果如下:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>
struct month
{
    char name[20];
    char abbr[4];
    int days;
    char number[3];
};
const 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 jiSuan(const char *, int, int);
int main(void){
    char input[20];
    int ri,year;
    int total;
    int flag;
    printf("请输入一个月份:\n");
    while (scanf("%s",input) == 1 && input[0] != 'q'){
        printf("请输入截止到这个月的几号:\n");
        flag = 0;
        scanf("%d",&ri);
        printf("请输入年份:\n");
        scanf("%d",&year);
        if ((year % 4 == 0 && year % 100 != 0)||year % 400 == 0){
            flag = 1;
        }
        total = jiSuan(input,ri,flag);
        if (total>0){
            printf("到%s月为止,一共有%d天。\n",input,total);
        }else{
            printf("输入的月份可能存在错误,请检查。\n");
        }
        printf("请输入下一个月份。输入q结束循环\n");   
    }
    printf("Done!!!");
    return 0;
}
int jiSuan(const char * in, int ri, int flag){
    int n = 0;
    int r = ri;
    for (int i = 0; i < 12; i++){
        if(strcmp(in,months[i].name) == 0 ||strcmp(in,months[i].abbr) == 0||strcmp(in,months[i].number) == 0){
            n = atoi(months[i].number);
        }
    }
    for (int i = 0; i < n-1; i++){
        r += months[i].days;
    }
    if (flag == 1 && n > 2){
        r += 1;
    }
    return r;
}

在这里插入图片描述

下面,我们来看一下第三题的要求,让我们修改程序清单14.2,然后按照几种顺序去输出图书信息。完整程序代码以及运行结果如下:

/* manybook.c -- 包含多本书的图书目录 */
#include <stdio.h>
#include <string.h>
char * s_gets(char * st, int n);
#define MAXTITL   40
#define MAXAUTL   40
#define MAXBKS   100         /* 书籍的最大数量  */

struct book {                /* 建立 book 模板     */
     char title[MAXTITL];
     char author[MAXAUTL];
     float value;
};
void ziMu(struct book library[MAXBKS],int count);
void jgMu(struct book library[MAXBKS],int count);
int main(void)
{
     struct book library[MAXBKS];    /*  book 类型结构的数组 */
     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')
               continue;        /* 清理输入行*/
          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);
          ziMu(library,count);
          jgMu(library,count);
     }
     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)                   // 如果地址不是 NULL,
               *find = '\0';          // 在此处放置一个空字符
          else
               while (getchar() != '\n')
                    continue;         // 处理输入行中剩余的字符
     }
     return ret_val;
}
void ziMu(struct book library[MAXBKS],int count){
     struct book libraryz[MAXBKS]; 
     struct book lz;
     for (int i = 0; i < count; i++){
          libraryz[i] = library[i];
     }
     for (int i = 0; i < count; i++){
          for (int j = i+1; j < count; j++){
               if (strcmp(libraryz[i].title,libraryz[j].title)>0){
                    lz = libraryz[i];
                    libraryz[i] = libraryz[j];
                    libraryz[j] = lz;
               }  
          }
     }
     printf("Here is the list of your books(按照字母顺序):\n");
     for (int index = 0; index < count; index++)
          printf("%s by %s: $%.2f\n", libraryz[index].title,
          libraryz[index].author, libraryz[index].value);
}
void jgMu(struct book library[MAXBKS],int count){
     struct book libraryj[MAXBKS]; 
     struct book lz;
     for (int i = 0; i < count; i++){
          libraryj[i] = library[i];
     }
     for (int i = 0; i < count; i++){
          for (int j = i+1; j < count; j++){
               if (libraryj[i].value > libraryj[j].value){
                    lz = libraryj[i];
                    libraryj[i] = libraryj[j];
                    libraryj[j] = lz;
               }  
          }
     }
     printf("Here is the list of your books(按照图书价格):\n");
     for (int index = 0; index < count; index++)
          printf("%s by %s: $%.2f\n", libraryj[index].title,
          libraryj[index].author, libraryj[index].value);
}

在这里插入图片描述

接着,来看一下第四题的内容,分析一下要求

在这里插入图片描述

创建一个含有两个成员的结构模版,其中一个成员是一个有三个成员的结构,初始化一个数组,内含五组数据,然后按照格式打印数据。说实话,这老外的名字格式我属实看的有点懵。那个是名字,那个又是姓,啥又是中间名啊。算了,按照自己的理解来吧。完整程序代码以及运行结果如下:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
#define SIZE 44
struct name{
     char ming[SIZE];
     char zhong[SIZE];
     char xing[SIZE];
};
struct test
{
     char shebao[100];
     struct name hpe;
};
struct test arr[5] ={
     {"302039823",{"Dribble","M","Flossie"}},
     {"231907821",{"Rell","C","Black"}},
     {"124324221",{"Dick","","James"}},
     {"124454545",{"Rose","","Kell"}},
     {"456565451",{"Pell","II","Gala"}}
};
void daYin(const struct test (*ptr));
void daYint(struct test ac[5]);
int main(void){
     struct test (*ptr) = arr;
     printf("----------程序开始----------\n");
     daYin(ptr);
     printf("----------------------------\n");
     daYint(arr);
     printf("----------程序结束----------\n");
     return 0;
}
void daYin(const struct test (*ptr)){
     for (int i = 0; i < 5; i++){
          if (strlen((ptr+i)->hpe.zhong) > 0){
               printf("%s, %s %s. -- %s\n",(ptr+i)->hpe.ming,(ptr+i)->hpe.xing
               ,(ptr+i)->hpe.zhong,(ptr+i)->shebao);
          }else{
               printf("%s, %s -- %s\n",(ptr+i)->hpe.ming,(ptr+i)->hpe.xing
               ,(ptr+i)->shebao);
          }
     }
}
void daYint(struct test ac[5]){
     for (int i = 0; i < 5; i++){
          if (strlen(ac[i].hpe.zhong) > 0){
               printf("%s, %s %s. -- %s\n",ac[i].hpe.ming,ac[i].hpe.xing
               ,ac[i].hpe.zhong,ac[i].shebao);
          }else{
               printf("%s, %s -- %s\n",ac[i].hpe.ming,ac[i].hpe.xing
               ,ac[i].shebao);
          }
     }
}

在这里插入图片描述

下面,我们来分析一下下一个问题的要求,主要是要去计算学生的平均成绩,用一个嵌套结构去记录数值。完整程序代码以及运行结果如下:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
#define SIZE 44
#define CSIZE 4
struct name
{
     char ming[SIZE];
     char xing[SIZE];
};
struct student
{
     struct name stu;
     float grade[3];
     float average;
};
int main(void){
     struct student students[CSIZE] = {
          {{"Rose","Hadden"}},
          {{"Hadvi","Dick"}},
          {{"James","Kell"}},
          {{"Yang","Auto"}}
     };
     for (int i = 0; i < CSIZE; i++){
          int sum = 0, count = 0;
          printf("请输入 %s %s 同学的成绩:\n",students[i].stu.ming,students[i].stu.xing);
          for (int j = 0; j < 3; j++){
               if (scanf("%f",&students[i].grade[j]) != 0){
                    sum += students[i].grade[j];
                    count++;
               }
          } 
          students[i].average = sum/count;          
     }
     printf("名字   姓氏  成绩1 成绩2 成绩3 平均成绩\n");
     for (int i = 0; i < CSIZE; i++){
          printf("%s %s %.2f %.2f %.2f %.2f\n",students[i].stu.ming,students[i].stu.xing,
          students[i].grade[0],students[i].grade[1],students[i].grade[2],
          students[i].average);
     }
     int sumb = 0;
     for (int i = 0; i < CSIZE; i++){
          sumb += students[i].average;
     }
     float ave = sumb / CSIZE;
     printf("班级的平均成绩为:%.2f\n",ave);
     return 0;
}

在这里插入图片描述

好的,接下来,来看一下第六题的要求是什么,处理一个垒球队的球员上场数据,计算后续的数据,比如安打率之类的高级数据。完整程序代码以及运行结果如下:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
#define SIZE 44
#define TXT "D:\\C\\test14.txt"
struct player
{
     int number;
     char ming[SIZE];
     char xing[SIZE];
     int shang;
     int ji;
     int zou;
     int rbi;
     float adl;
};
struct player players[19] = {
     {0,"","",0,0,0,0,0},{0,"","",0,0,0,0,0},{0,"","",0,0,0,0,0},
     {0,"","",0,0,0,0,0},{0,"","",0,0,0,0,0},{0,"","",0,0,0,0,0},
     {0,"","",0,0,0,0,0},{0,"","",0,0,0,0,0},{0,"","",0,0,0,0,0},
     {0,"","",0,0,0,0,0},{0,"","",0,0,0,0,0},{0,"","",0,0,0,0,0},
     {0,"","",0,0,0,0,0},{0,"","",0,0,0,0,0},{0,"","",0,0,0,0,0},
     {0,"","",0,0,0,0,0},{0,"","",0,0,0,0,0},{0,"","",0,0,0,0,0}
};
int main(void){
     FILE * in;
     int count;
     int n, s, j, z, r;
     float a;
     char m[SIZE], x[SIZE];
     if((in = fopen(TXT,"r")) == NULL){
          fprintf(stderr,"无法打开文件%s",TXT);
          exit(EXIT_FAILURE);
     }
     rewind(in);
     while (feof(in) != 1 &&(count = fscanf(in,"%d %s %s %d %d %d %d",&n,m,x,&s,&j,&z,&r)) && count == 7){
          players[n].number = n;
          strcpy(players[n].ming,m);
          strcpy(players[n].xing,x);
          players[n].shang += s;
          players[n].ji += j;
          players[n].zou += z;
          players[n].rbi += r;          
     }
     printf("号码   名字   姓氏   上场数   击中数   走垒数   RBI   安打率\n");
     for (int i = 0; i < 19; i++){
          if (players[i].shang > 0){
               a = (float)players[i].ji/(float)players[i].shang;
          }else{
               a = 0;
          }
          players[i].adl = a;
          printf("%-5d %-6s %-6s %5d %7d %9d %6d %7.2f\n",players[i].number,players[i].ming,
          players[i].xing,players[i].shang,players[i].ji,players[i].zou,players[i].rbi,a);
     }
    
     return 0;
}

在这里插入图片描述

接着,我们来看一下第七题的要求以及具体实现思路,要求我们去修改程序清单14.14,然后增加一个修改以及删除文件中的图书信息,这一个确实比较复杂,用了很长时间,也没有做出最终的效果,只是粗略的实现了一下这部分的功能,其实还有很大的优化空间。我们来看一下程序的完整代码以及运行结果:

/* booksave.c -- 在文件中保存结构中的内容 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXTITL  40
#define MAXAUTL  40
#define MAXBKS   10             /* 最大书籍数量 */
char * s_gets(char * st, int n);
struct book {                   /* 建立 book 模板 */
     char title[MAXTITL];
     char author[MAXAUTL];
     float value;
     int delete;
};
void update(struct book * lbi,int n);
int main(void)
{
     struct book library[MAXBKS]; /* 结构数组  */
     int count = 0;
     int index, filecount;
     FILE * pbooks;
     int size = sizeof(struct book);

     char yn,ud;
     int delcount = 0;

     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:");
          if (library[count].delete == 0){
               printf("%s by %s: $%.2f\n", library[count].title,
                    library[count].author, library[count].value);
               printf("是否要对该条内容执行修改或删除操作(y/n):\n");
               scanf("%c",&yn);
               while (getchar() != '\n'){
                    continue;
               }
               if (yn == 'y'){
                    printf("如要执行修改操作请输入u,删除操作请输入d。\n");
                    scanf("%c",&ud);
                    while (getchar() != '\n'){
                         continue;
                    }
                    if (ud == 'u'){
                         printf("开始修改\n");
                         update(library,count);
                         printf("已修改\n");
                    }else if (ud == 'd'){
                         printf("已删除\n");
                         library[count].delete = 1;
                         delcount++;
                    }
               }
               count++;
          }
          
     }
     filecount = count - delcount;
     if (filecount == MAXBKS)
     {
          fputs("The book.dat file is full.", stderr);
          exit(2);
     }
     int newcount = 0, newH =0;
     if (delcount > 0){
          while (library[newcount].delete == 0){
               newcount++;
          }
          count = newcount;
     }
     puts("Please add new book titles.");
     puts("Press [enter] at the start of a line to stop.");
     while (filecount < 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);
          library[count].delete = 0;
          while (getchar() != '\n')
               continue;            /* 清理输入行  */
          if (count < MAXBKS)
               puts("Enter the next title.");
          newH++;
          if (delcount > 0){
               while (library[newcount].delete == 0){
                    newcount++;
               }
               count = newcount;
          }else{
               count++;
          } 
     }
     int nownumber = filecount + newH;
     if (nownumber > 0)
     {
          rewind(pbooks);
          puts("Here is the list of your books:");
          for (index = 0; index < nownumber; index++){
               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;
}

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)                // 如果地址不是 NULL,
               *find = '\0';            // 在此处放置一个空字符
          else
               while (getchar() != '\n')
                    continue;        // 清理输入行
     }
     return ret_val;
}
void update(struct book * lbi,int n){
     struct book the;
     printf("暂不支持修改单个数据,请重新输入该条图书数据。\n");
     puts("请输入要修改的图书名。");
     s_gets(the.title,MAXTITL);
     puts("请输入图书作者。");
     s_gets(the.author, MAXAUTL);
     puts("请输入图书价格。");
     scanf("%f", &the.value);
     the.delete = 0;
     while (getchar() != '\n')
               continue;  
     *(lbi + n) = the;
}

首先是,从零添加图书,结果如下

在这里插入图片描述

然后再次运行程序,回显这些文件,并测试修改以及删除操作

在这里插入图片描述

观察得知,修改操作已经没有问题,但是还可以优化,比如单独修改其中的某个值,这里就先不讨论了,我们再去改一下删除的问题。又仔细看了一下,发现好像是在选择操作的时候输错了值,跳过了一步,导致删除没有成功,我们再单独测试一遍删除操作。

在这里插入图片描述

由此可见,没有问题,再测试一下只删除,不添加的操作。

在这里插入图片描述

好,综上,这一个问题就简单的实现了基本的要求,当然如果时间充裕的话,还可以像我说的一样,进行用户使用体验的优化,比如可以选择修改某个值,其实实现起来也不是很难,毕竟你全部更新都实现了,更新单个值的内容的话,只是还要加一步选择操作。自己思考这来实现吧。下面,我们来看一下第八题的要求。

在这里插入图片描述

巨人航空公司,哈哈,讲道理不怕艾伦塔塔开你吗?开玩笑哈,我们接着看要求。飞机上有十二个座位,每天飞行一个航班,给了我们结构的数据内容,实现菜单的内容,:选择方法,输入其字母标签,a:显示空座位数,b:显示空座位列表,c:显示按字母顺序排列的座位列表,d:为客户分配座位,e:删除座位分配,f:退出,选择d或者e提示用户进行额外输入,好,下面来看一下具体实现以及运行结果:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>
#define SEATNUMBER 12
#define SIZE 44
struct seat
{
     char number[SIZE];
     int flag;//0表示没有被预定,1表示已经被预定
     char ming[SIZE];
     char xing[SIZE];
};
struct seat seats[SEATNUMBER] = {
     {"JR-A1",0,"",""},{"JR-B1",0,"",""},{"JR-C1",0,"",""},
     {"JR-A2",0,"",""},{"JR-B2",0,"",""},{"JR-C2",0,"",""},
     {"JR-A3",0,"",""},{"JR-B3",0,"",""},{"JR-C3",0,"",""},
     {"JR-A4",0,"",""},{"JR-B4",0,"",""},{"JR-C4",0,"",""}
};

void showMenu(void);
char getCz(void);
char * s_gets(char * st, int n);
void functionA();
void functionB();
void functionC();
void functionD();
void functionE();

int main(void){
     char ch;
     printf("巨人航空公司欢迎您,请选择您要办理的业务\n");
     showMenu();
     ch = getCz();
     while (getchar() != '\n')
          continue;
     while (ch != 'f'){
          switch (ch)
          {
          case 'a':
               functionA();
               break;
          case 'b':
               functionB();
               break;
          case 'c':
               functionC();
               break;
          case 'd':
               functionD();
               break;
          case 'e':
               functionE();
               break;
          
          default:
               break;
          }
          showMenu();
          ch = getCz();
          while (getchar() != '\n')
          continue;
     }
     printf("Done!!!\n");
     return 0;
}
void showMenu(void){
     printf("-------------------------菜单-------------------------\n");
     printf("请选择要进行的操作,输入其字母标签\n");
     printf("a)显示空座位数                 b)显示空座位列表 \n");
     printf("c)显示按字母顺序排列的座位列表  d)为客户分配座位  \n");
     printf("e)删除座位分配                 f)退出     \n");
     printf("------------------------------------------------------\n");
}
char getCz(void){
    char input;
    while (scanf("%c",&input)!=1||(input != 'a'&&input != 'b'&&input != 'c'&&
          input != 'd'&&input != 'e'&&input != 'f')){
        printf("您输入的值不合法,请重新输入!!\n");
        while (getchar() != '\n')
          continue;
    }
    return input;
}
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)                // 如果地址不是 NULL,
               *find = '\0';            // 在此处放置一个空字符
          else
               while (getchar() != '\n')
                    continue;        // 清理输入行
     }
     return ret_val;
}
void functionA(){
     int number = 0;
     for (int i = 0; i < SEATNUMBER; i++){
          if (seats[i].flag == 0){
               number++;
          }
     }
     printf("当前航班上还有%d个座位没有被预定\n",number);
}
void functionB(){
     int number = 0;
     printf("当前航班上空座位列表如下:\n");
     for (int i = 0; i < SEATNUMBER; i++){
          if (seats[i].flag == 0){
               number++;
               printf("%2d)%s\n",number,seats[i].number);
          }
     }
}
void functionC(){
     struct seat copy[SEATNUMBER];
     struct seat cc;
     for (int i = 0; i < SEATNUMBER; i++){
          copy[i] = seats[i];
     }
     for (int i = 0; i < SEATNUMBER; i++){
          for (int j = i + 1; j < SEATNUMBER; j++){
               if (strcmp(copy[i].number,copy[j].number) > 0){
                    cc = copy[i];
                    copy[i] = copy[j];
                    copy[j] = cc;
               }
          }
     }
     int number = 0;
     for (int i = 0; i < SEATNUMBER; i++){
          number++;
          if (copy[i].flag == 1){
               printf("%2d)%s  已预订\n",number,copy[i].number);
          }else{
               printf("%2d)%s  可预订\n",number,copy[i].number);
          }   
     }
}
void functionD(){
     int count = 0;
     printf("请为客户分配座位,输入空行结束\n");
     printf("请输入客户的名字\n");
     while (count < SEATNUMBER && s_gets(seats[count].ming, SIZE) != NULL &&
      seats[count].ming[0] != '\0' &&seats[count].flag != 1){
          printf("请输入客户的姓氏\n");
          s_gets(seats[count].xing, SIZE);
          seats[count].flag = 1;
          count++;
          printf("这位客户的座位已经分配好,请输入下一位客户的信息\n");
     }
     printf("座位分配结束或者座位已满\n");
}
void functionE(){
     int count = 0;
     int number = 0;
     char yn;
     printf("请开始删除座位分配\n");
     while (count < SEATNUMBER){
          if (seats[count].flag == 1){
               number++;
               printf("%2d) %s 已预订 %s %s\n",number,seats[count].number,
               seats[count].ming,seats[count].xing);
               printf("是否删除该座位分配(y/n):\n");
               scanf("%c",&yn);
               while (getchar() != '\n')
                    continue;
               if (yn == 'y'){
                    seats[count].flag = 0;
               }  
          }
          count++;
     }
}

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

ok,我们依次进行了每个菜单的功能演示,从展示空座位列表,到预订,然后再次展示空座位数以及空座位列表,然后删除预订之后,再次展示空座位数以及空座位列表,没有问题,小细节可以优化的部分暂时不唠了,毕竟这一章的编程练习搞了好长时间了,还没有搞完。接下来,我们来看第九题的要求。将第八题扩展为可以满足四个航班,下面我们看一下程序实现以及运行结果:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>
#define SEATNUMBER 12
#define SIZE 44
struct seat
{
     char number[SIZE];
     int flag;//0表示没有被预定,1表示已经被预定
     char ming[SIZE];
     char xing[SIZE];
};
struct seat seats[SEATNUMBER] = {
     {"JR-A1",0,"",""},{"JR-B1",0,"",""},{"JR-C1",0,"",""},
     {"JR-A2",0,"",""},{"JR-B2",0,"",""},{"JR-C2",0,"",""},
     {"JR-A3",0,"",""},{"JR-B3",0,"",""},{"JR-C3",0,"",""},
     {"JR-A4",0,"",""},{"JR-B4",0,"",""},{"JR-C4",0,"",""}
};
char hb[4][SIZE] = {
     "巨航102","巨航311","巨航444","巨航519"
};

void showHb(void);
void showMenu(int hbn);
char getCz(void);
char * s_gets(char * st, int n);
void functionA(int hbn);
void functionB(int hbn);
void functionC(int hbn);
void functionD(int hbn);
void functionE(int hbn);
void functionF(int hbn);

int main(void){
     char ch;
     char hh;
     printf("巨人航空公司欢迎您,请选择您要办理的业务\n");
     showHb();
     hh = getCz();
     while (getchar() != '\n')
          continue;
     while (hh != 'f'){
          int hbn = (int)hh - (int)'a';
          showMenu(hbn);
          ch = getCz();
          while (getchar() != '\n')
               continue;
          while (ch != 'g'){
               switch (ch)
               {
               case 'a':
                    functionA(hbn);
                    break;
               case 'b':
                    functionB(hbn);
                    break;
               case 'c':
                    functionC(hbn);
                    break;
               case 'd':
                    functionD(hbn);
                    break;
               case 'e':
                    functionE(hbn);
               break;
               case 'f':
                    functionF(hbn);
               break;

               default:
                    break;
          }
          showMenu(hbn);
          ch = getCz();
          while (getchar() != '\n')
               continue;
          }
          showHb();
          hh = getCz();
          while (getchar() != '\n')
               continue;
     }
     
     printf("Done!!!\n");
     return 0;
}
void showHb(void){
     char n = 'a';
     printf("-----------------------航班信息------------------------\n");
     for (int i = 0; i < 4; i++){
          printf("%c) %s\n",n,hb[i]);
          n++;
     }
     printf("%c) 退出程序\n",n);
     printf("-------------------------------------------------------\n");
}
void showMenu(int hbn){
     printf("------------------%s-----菜单-------------------------\n",hb[hbn]);
     printf("请选择要进行的操作,输入其字母标签\n");
     printf("a)显示空座位数                 b)显示空座位列表 \n");
     printf("c)显示按字母顺序排列的座位列表  d)为客户分配座位  \n");
     printf("e)删除座位分配                 f)确认座位分配     \n");
     printf("g)退出 \n");
     printf("------------------------------------------------------\n");
}
char getCz(void){
    char input;
    while (scanf("%c",&input)!=1 || input < 'a' || input > 'g'){
        printf("您输入的值不合法,请重新输入!!\n");
        while (getchar() != '\n')
          continue;
    }
    return input;
}
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)                // 如果地址不是 NULL,
               *find = '\0';            // 在此处放置一个空字符
          else
               while (getchar() != '\n')
                    continue;        // 清理输入行
     }
     return ret_val;
}
void functionA(int hbn){
     int number = 0;
     for (int i = 0; i < SEATNUMBER; i++){
          if (seats[i].flag == 0){
               number++;
          }
     }
     printf("%s航班上还有%d个座位没有被预定\n",hb[hbn],number);
}
void functionB(int hbn){
     int number = 0;
     printf("%s航班上空座位列表如下:\n",hb[hbn]);
     for (int i = 0; i < SEATNUMBER; i++){
          if (seats[i].flag == 0){
               number++;
               printf("%2d)%s %s\n",number,hb[hbn],seats[i].number);
          }
     }
}
void functionC(int hbn){
     struct seat copy[SEATNUMBER];
     struct seat cc;
     for (int i = 0; i < SEATNUMBER; i++){
          copy[i] = seats[i];
     }
     for (int i = 0; i < SEATNUMBER; i++){
          for (int j = i + 1; j < SEATNUMBER; j++){
               if (strcmp(copy[i].number,copy[j].number) > 0){
                    cc = copy[i];
                    copy[i] = copy[j];
                    copy[j] = cc;
               }
          }
     }
     int number = 0;
     for (int i = 0; i < SEATNUMBER; i++){
          number++;
          if (copy[i].flag == 1){
               printf("%2d) %s  %s  已预订\n",number,hb[hbn],copy[i].number);
          }else{
               printf("%2d) %s  %s  可预订\n",number,hb[hbn],copy[i].number);
          }   
     }
}
void functionD(int hbn){
     int count = 0;
     printf("请为客户在航班%s上分配座位,输入空行结束\n",hb[hbn]);
     printf("请输入客户的名字\n");
     while (count < SEATNUMBER && s_gets(seats[count].ming, SIZE) != NULL &&
      seats[count].ming[0] != '\0' &&seats[count].flag != 1){
          printf("请输入客户的姓氏\n");
          s_gets(seats[count].xing, SIZE);
          seats[count].flag = 1;
          count++;
          printf("这位客户的座位已经分配好,请输入下一位客户的信息\n");
     }
     printf("%s航班座位分配结束或者座位已满\n",hb[hbn]);
}
void functionE(int hbn){
     int count = 0;
     int number = 0;
     char yn;
     printf("请开始删除%s航班上的座位分配\n",hb[hbn]);
     while (count < SEATNUMBER){
          if (seats[count].flag == 1){
               number++;
               printf("%2d) %s %s 已预订 %s %s\n",number,seats[count].number,
               hb[hbn],seats[count].ming,seats[count].xing);
               printf("是否删除该座位分配(y/n):\n");
               scanf("%c",&yn);
               while (getchar() != '\n')
                    continue;
               if (yn == 'y'){
                    seats[count].flag = 0;
               }  
          }
          count++;
     }
}
void functionF(int hbn){
     int count = 0;
     int number = 0;
     char yn;
     printf("请开始确认%s航班上的座位分配\n",hb[hbn]);
     while (count < SEATNUMBER){
          if (seats[count].flag == 1){
               number++;
               printf("%2d) %s %s 已预订 %s %s\n",number,seats[count].number,
               hb[hbn],seats[count].ming,seats[count].xing);
               printf("是否确认该座位分配(y/n):\n");
               scanf("%c",&yn);
               while (getchar() != '\n')
                    continue;
               if (yn == 'y'){
                    seats[count].flag = 1;
               }else{
                    seats[count].flag = 0;
               }  
          }
          count++;
     }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

上面,我们依次展示航班,菜单,展示空座位数以及空座位列表,然后为用户预订座位,然后在确认座位的时候一个确认,一个不进行确认,再次展示空座位数以及空座位列表,接着退出菜单,再次退出程序,结束程序。接着,我们再看一下第十题要求我们做一些什么操作。编写一个程序,通过函数指针数组去实现菜单,然后选择菜单中的值,激活对应的函数。我们简单的去实现一下这个思想要求的内容,所以具体的函数没有使用复杂的。完整程序代码以及运行结果如下:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>

void showMenu(void);
char getCz(void);
void functionA(void);
void functionB(void);
void functionC(void);

int main(void){
     void (* ptr[3]) (void) = {functionA,functionB,functionC};
     char ch;
     showMenu();
     ch = getCz();
     while (getchar() != '\n')
          continue;
     while (ch != 'd'){
          int n = (int)ch - (int)'a';
          switch (ch)
          {
          case 'a':
               ptr[n]();
               break;
          case 'b':
               ptr[n]();
               break;
          case 'c':
               ptr[n]();
               break;

          default:
               break;
          }
          showMenu();
          ch = getCz();
          while (getchar() != '\n')
          continue;
     }
     
     return 0;
}
void showMenu(void){
     printf("------------------------------------------\n");
     printf("a) 方法A    \n");
     printf("b) 方法B    \n");
     printf("c) 方法C    \n");
     printf("d) 退出    \n");
     printf("------------------------------------------\n");
}
char getCz(void){
    char input;
    while (scanf("%c",&input)!=1 || input < 'a' || input > 'd'){
        printf("您输入的值不合法,请重新输入!!\n");
        while (getchar() != '\n')
          continue;
    }
    return input;
}
void functionA(void){
     printf("-------------方法A开始运行----------------\n");
     printf("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n");
     printf("-------------方法A结束运行----------------\n");
}
void functionB(void){
     printf("-------------方法B开始运行----------------\n");
     printf("BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n");
     printf("-------------方法B结束运行----------------\n");
}
void functionC(void){
     printf("-------------方法C开始运行----------------\n");
     printf("CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n");
     printf("-------------方法C结束运行----------------\n");
}

在这里插入图片描述

接着,我们再看一下本章的最后一个编程练习的要求,编写一个函数,函数名已经给了我们,所接受的四个参数也已经规定了,分别是,内含double数据的源数组名、内含double数据的目标数组名、表示数组元素个数的int数据、函数指针。函数把指定函数应用于源数组的每个元素,将返回值放到目标数组之中,测试该函数四次,使用两个math.h中的函数,两个自定义的函数。下面看一下完整程序以及运行结果:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
#include<math.h>
#define SIZE 40
void transform(const double * trage,double * source,int count,double (* ptr)(double));
double functionE(double n);
double functionD(double n);
void showArr(const double * ac,int n);
int main(void){
     double arr[SIZE];
     for (int i = 0; i < SIZE; i++){
          arr[i]= i;
     }
     double ac[SIZE];
     printf("--------第一次调用-------------\n");
     transform(arr,ac,SIZE,sin);
     showArr(ac,SIZE);
     printf("--------第二次调用-------------\n");
     transform(arr,ac,SIZE,cos);
     showArr(ac,SIZE);
     printf("--------第三次调用-------------\n");
     transform(arr,ac,SIZE,functionE);
     showArr(ac,SIZE);
     printf("--------第四次调用-------------\n");
     transform(arr,ac,SIZE,functionD);
     showArr(ac,SIZE);
     return 0;
}
void transform(const double * source,double * trage,int count,double (* ptr)(double)){
     for (int i = 0; i < count; i++){
          *(trage + i) = ptr(*(source + i));
     }
}
double functionE(double n){
     double r;
     r = 2*n;
     return r;
}
double functionD(double n){
     double r;
     r = 1/n;
     return r;
}
void showArr(const double * ac,int n){
     for (int i = 0; i < n; i++){
          printf("%.2f ",*(ac+i));
          if (i%9==0 && i != 0){
               printf("\n");
          }        
     } 
     printf("\n");
}

在这里插入图片描述

最后一个问题并不是很麻烦,在实现的时候呢,我们先是调用了math.h中的sin()函数和cos()函数,然后自己写了两个函数,分别求取值的二倍以及倒数,分别调用并展示处理之后得到的数据。以上就是本章的编程练习,总体来说还是比较有东西的,毕竟搞了这么好几天呢。第十四章暂时告一段落,接着,我们就要去看一下书上关于第十五章位操作的内容了。

  • 29
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值