C Prime Plus中文第六版编程题——第十四章练习

文章目录

1.

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

可识别月号,月全拼,月缩写

code

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int count_days(char *str);
char* s_gets(char *str,int n);
struct month {
    char name[10];
    char abbr[4];
    int days;
             };
 struct month months[12]={
                {"January","jan",31},  {"February","feb",28},  {"March","mar",31},
   {"Aprill","apr",30},   {"May","may",31},      {"June","jun",30} ,
    {"July","jul",31},    {"August","aug",31},   {"Sepetember","sep",30},
    {"October","oct",31},  {"November","nov",30},  {"December","dec",31},  
                                   };

int main()
{
       char get_month[10];
       printf("Enter a month\n(press Enter in a new line to quit ):\n");
       while(    s_gets(get_month,10) !=NULL && get_month[0]!='\0'          )
         { 
             
             count_days(get_month);                         
           
                 printf("Another month or press Enter in new line to quit:\n");  
                     }printf("Bye!\n");
                     
          return 0;
}
char* s_gets(char *str,int n)
{
    char *ret_val;
    char *find;
    ret_val=fgets(str,n,stdin);
       if (ret_val)  {
/*若接受的不是空line,有两种情况,一是没读满字符上限就完成了string的全部输入,此时要将末尾的
换行符换成'\0',第二种情况是输入的字符多于读取上限,此时要把缓冲区的多余输入全部清除*/
            find=strchr(str,'\n');
            if(find)
             *find='\0';
             else
              while( getchar()!='\n')
                           continue;}
                           return ret_val;
             
}
int count_days(char *str)
{
    extern struct month months[];
    int sum=0;
    int i=0;
if (    isdigit(str[0])   )
        i=atoi(str)-1;  //8月在months[12]中的下标为7.
else
     {while(strcmp(months[i].abbr,str)!=0 && strcmp(months[i].name,str)!=0 && i<12)
           i++;
        }
           if (i>=12 || i<0) //如果比过了struct的十二个结构元素,都没有和输入相同的字符串,此时i=11+1
              {printf("This is not a valid input\n");
              return 0;} 
           
             for (int count=0;count<=i;count++)
              {    sum+=months[count].days;   }
              printf("The total days from January 1st to the last day of the %s are %d\n",months[i].name,sum);
              return 0;
}

result

在这里插入图片描述


2.

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

code

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
struct info {int year;int day; char month[10]; }; 
struct month {char name[10];char abbr[4];int days;};
struct month months[12]={  {"January","jan",31},  {"February","feb",28},  {"March","mar",31},
                           {"Aprill","apr",30},   {"May","may",31},      {"June","jun",30} ,
                           {"July","jul",31},    {"August","aug",31},   {"Sepetember","sep",30},
                           {"October","oct",31},  {"November","nov",30},  {"December","dec",31},  
                         };
int count_day(struct info input_got);
struct info get_info(struct info input);    
int main()
{
   struct info input;
    int enter_or_exit=1;
    while(enter_or_exit==1)
  {input=get_info(input);
   count_day(input);
   while(getchar()!='\n')
           continue;
    printf("Enter 1 to continue, 0 to exit input:\n");
    scanf("%d",&enter_or_exit);
  }printf("Bye!\n");
     return 0;
}
struct info get_info(struct info input){
     printf("Please input a day in such way:[year] [month] [day]:\n");
    printf("The [month] can be a month number,a month abbreviation or a full write:\n");
    while(  scanf("%d %s %d",&input.year,&input.month,&input.day)!=3)
    {printf("Sorry, the  input can't be recognized,please try again");}
    return input;
    }
int count_day(struct info input_got)
{
  int sum=0;
  int i=0;
   if (    isdigit(input_got.month[0])        )//若输入为月份号
        i=atoi(input_got.month)-1; //i是months[12]数组的下标
        else //若输入的是全拼或缩写
        {while(strcmp(months[i].abbr,input_got.month)!=0 && strcmp(months[i].name,input_got.month)!=0 && i<12)
           i++;
        }
          for (int count=0;count<i;count++)
              {    sum+=months[count].days;   }
              //目前计算了该月之前的月总天数
              sum+=input_got.day;//加上本月天数
              if(   (input_got.year%4) == 0  && i>=2)
             sum=sum+1;
               //如果是闰年,输入的月份大于2月(i是下标),则总天数要加上2月29那一天
              printf("The total days from the year beginning to the %d %s %d : %d\n",
                                              input_got.year,months[i].name,input_got.day,sum);
              return 0;
}

result

在这里插入图片描述
没有写判断输入错误并反馈的代码了,能错的地方好多。。。


3.

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

code

/* manybook.c -- multiple book inventory */
#include <stdio.h>
#include <string.h>
char * s_gets(char * st, int n);
#define MAXTITL   40
#define MAXAUTL   40
#define MAXBKS   100              /* maximum number of books  */

struct book {                     /* set up book template     */
    char title[MAXTITL];
    char author[MAXAUTL];
    float value;
};
void show_in_price(int n,struct book arr[100]);
void show_in_alphabet(int n,struct book arr[100]);
int main(void)
{
    struct book library[MAXBKS]; /* array of book structures */
    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;          /* clear input line         */
        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");
if(count>0)
    {	
        printf("\n");
        show_in_alphabet(count,library);
        printf("\n");
    	show_in_price(count,library);
    }
    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');   // look for newline
        if (find)                  // if the address is not NULL,
            *find = '\0';          // place a null character there
        else
            while (getchar() != '\n')
                continue;          // dispose of rest of line
    }
    return ret_val;
}
void show_in_alphabet(int n,struct book arr[n])
{
    struct book temp;
    for(int i=0;i<n-1;i++)
     {
         for(int j=i+1;j<n;j++)
         {
             if (strcmp(arr[i].title,arr[j].title)>0) //大于0说明是"B" "A"的顺序
              {temp=arr[i];arr[i]=arr[j];arr[j]=temp;}
         }
     }
   printf("Here is the list of your books in  alphabet:\n");
        for (int index = 0; index < n; index++)
            printf("%s by %s: $%.2f\n", arr[index].title,
                   arr[index].author, arr[index].value);
    }
   

	
void show_in_price(int n,struct book arr[n])
	{
    struct book temp;
    for(int i=0;i<n-1;i++)
     {
         for(int j=i+1;j<n;j++)
         {
             if (arr[j].value<arr[i].value) //升序排列:如果后面的比前面的小,小的放前面去
              {temp=arr[i];arr[i]=arr[j];arr[j]=temp;}
         }
     }
   printf("Here is the list of your books from low price to high:\n");
        for (int index = 0; index < n; index++)
            printf("%s by %s: $%.2f\n", arr[index].title,
                   arr[index].author, arr[index].value);
    }

result

在这里插入图片描述


4.

编写一个程序,创建一个有两个成员的结构模板:
a.第1个成员是社会保险号,第2个成员是一个有3个成员的结构,第1个成员代表名,第2个成员代表中间名,第3个成员表示姓。创建并初始化一个内含5个该类型结构的数组。该程序以下面的格式打印数据:Dribble, Flossie M.–– 302039823如果有中间名,只打印它的第1个字母,后面加一个点(.);如果没有中间名,则不用打印点。编写一个程序进行打印,把结构数组传递给这个函数。
b.修改a部分,传递结构的值而不是结构的地址。

code

//part_a 传递地址 (结构指针可以接收数组地址或结构地址,不要定义一个指向arr[5]的指针(*ptr)[5])
//对于指向数组的指针,int (*ptr)[5]一般是用在二维数组arr[n][5]中,每次跳一行。
//处理一维数组arr[n],ptr就够了
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct person {char first_name[20];char middle_name[20];char last_name[20];};
struct ID_card {char id[6];struct person name;};
void show_ID_1(int n,struct ID_card (*ptr));
int main()
{
    struct ID_card storage[5]={  {"00001", {"Erich","Maria","Remarque"}       },
                                 {"00011", {"Rainer", "Maria" ,"Rilke"}       },
                                 {"00111", {"Angela", "Dorothea" ,"Merkel" }  },
                                 {"01111", {"Angela", "Dorothea" ,"Merkel" }  },
                                 {"11111", {"Jingtong", "\0"  ,"Peng" }       },   
                                                                                 };   
                                 
                           show_ID_1(5,storage);   
                                
      
                                 
    return 0;
}
void show_ID_1(int n,struct ID_card (*ptr)  )
{
  for(int i=0;i<5;i++)
    {
        
     if(   strcmp  (      (ptr+i)->name.middle_name  , "\0" )  ==0      )
           printf("%s,%s--%s\n",
(ptr+i)->name.first_name , (ptr+i)->name.last_name , (ptr+i)->id );
   
     else 
        printf("%s,%s %c.--%s\n",
(ptr+i)->name.first_name , (ptr+i)->name.last_name , (ptr+i)->name.middle_name[0] , (ptr+i)->id );
     
     }   
}
//part_b
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct person {char first_name[20];char middle_name[20];char last_name[20];};
struct ID_card {char id[6];struct person name;};
void show_ID_1(int n,struct ID_card storage[n]);
int main()
{
    struct ID_card storage[5]={  {"00001", {"Erich","Maria","Remarque"}       },
                                 {"00011", {"Rainer", "Maria" ,"Rilke"}       },
                                 {"00111", {"Angela", "Dorothea" ,"Merkel" }  },
                                 {"01111", {"Angela", "Dorothea" ,"Merkel" }  },
                                 {"11111", {"Jingtong", "\0"  ,"Peng" }       },   
                                                                                 };   
                                 
                           show_ID_1(5,storage);   
                                                       
    return 0;
}
void show_ID_1(int n,struct ID_card storage[n])
{
  for(int i=0;i<5;i++)
    {
        
     if(   strcmp (storage[i].name.middle_name  , "\0" )==0   )
           printf("%s,%s--%s\n",
storage[i].name.first_name , storage[i].name.last_name , storage[i].id );
   
     else 
        printf("%s,%s %c.--%s\n",
storage[i].name.first_name , storage[i].name.last_name , storage[i].name.middle_name[0] , storage[i].id );
     
     }   
}

result

在这里插入图片描述


5.

编写一个程序满足下面的要求。
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.打印班级的平均分,即所有结构的数值成员的平均值。

code

#include <stdio.h>
#include <stdlib.h>
#define CSIZE 4
#include <string.h>
struct name {
              char n_first[40];
              char n_last[20];
             };
struct student {
    struct name ful_name;
    float grade[3];
    float average; 
   };

void get_score( int n, struct student *ptr);
void show_score(int n, struct student *ptr);
float calculate_average(int n, struct student *ptr);
 char * s_gets(int size , char *str);
int main()
{
    float class_average;
    struct student class_mate[CSIZE]= {
                  {     .ful_name= {  "Zhang"  ,  "San"  }    },
                  {     .ful_name= {     "Li"  ,  "Si"   }    },
                  {     .ful_name= {   "Wang"  ,  "Wu"   }    },
                  {     .ful_name= {   "Zhao"  ,  "Liu"  }    }
                                       };
                                       
get_score( 4,class_mate );     //录入分数
class_average= calculate_average(4,class_mate);//把每个人的平均值录入结构,把班级平均分return给class_average
show_score(4,class_mate );       //展示结构内容
printf("\nThe average score of the class is %.2f\n",class_average) ;                                      
                                       
    return 0;
}

void get_score( int n, struct student *ptr)
{
         int i=0;   //i为已经得到的有效名字数,若名字输入错误不会自增
         char get_name[60];
         char *check_eof;
          char ful_name[n][60];
  for (int k=0;k<n;k++)//将姓和名拼接在一起存入ful_name数组,之后和输入的名字get_name做对比
           {
              strcpy( ful_name[k] , (ptr+k)->ful_name.n_first );
              strcat( ful_name[k] , " " );
              strcat( ful_name[k] , (ptr+k)->ful_name.n_last );
           }
           
         printf("Enter a student name, please(press Enter in a new line to quit):\n");
  while(     i<n   &&  ( check_eof=s_gets(60,get_name) )!=NULL && get_name[0]!='\0'      )  //有效输入小于class mate总数n,且输入的名字不是回车时执行循环
    {
         int j=0;
   while( j<n   && strcmp(    get_name   ,   ful_name[j]      )!=0)//对输入的名字循环查找班级名单
                 j++;
             if ( j==n) //若循环名单结束仍然没找到名字,则反馈错误信息
             {printf("The student %s is not in class, please re-enter:\n",get_name);
                          
                 continue;  //返回大循环:要求用户重新输入字符给get_name
              }
             else //若找到名单中的学生
               {printf("Please enter the score in such way ([quiz 1] [quiz 2] [quiz 3]):\n");
                i++;
  scanf(   "%f %f %f",  & ( (ptr+j)->grade[0] )  ,   &( (ptr+j)->grade[1] )   ,   &( (ptr+j)->grade[2] )   );//录入分数
                while (   getchar()!='\n'   )//清除scanf产生的回车
                continue;
              }
             if(i<4)
             printf("Next student:\n");
              
    } printf("\nInput done!\n");//输入满名单数量n或收到回车
}    
     
char * s_gets(int size , char *str){
        char *ret_val;
        char *find;
        ret_val=fgets(str,size,stdin);
        if(ret_val)
          { find=strchr(str,'\n');
              if(find)
              *find='\0';
              else 
            while (getchar()!='\n')
             continue; }
             return ret_val;
}

void show_score(int n, struct student *ptr){
    printf("\n");
    for(int i=0;i<n;i++)
        printf("%s %s\nScore:%.2f %.2f %.2f   average: %.2f\n", 
        (ptr+i)->ful_name.n_first , (ptr+i)->ful_name.n_last , (ptr+i)->grade[0] , (ptr+i)->grade[1] , (ptr+i)->grade[2],  (ptr+i)->average);
}
float calculate_average(int n, struct student *ptr){
    float sum=0;
    for(int i=0;i<n;i++)
     { (ptr+i)->average  = ( (ptr+i)->grade[0] + (ptr+i)->grade[1] + (ptr+i)->grade[2] )/3 ;
      sum+=(ptr+i)->average;}
      return sum/n;
}

result

在这里插入图片描述


6.

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

code

//T14.6
#include <stdio.h>
#include <stdlib.h>
#define AMOUNT 5
#define NAME_SIZE 20
struct info {
        char first_name[NAME_SIZE]; 
        char last_name[NAME_SIZE]; 
        int at_bat;
        int hit_count;
        int walk_count;
        int RBI;
        float batting_average;
};
int main()
{
    struct info player[AMOUNT];
    FILE *fp;
    struct get_info { int number; char first_name[NAME_SIZE]; char last_name[NAME_SIZE]; int at_bat; int hit_count; int walk_count; int RBI; };
    struct get_info temp;
    
    //initial
    for(int i=0;i<AMOUNT;i++)
     {
         player[i].at_bat=0;
         player[i].hit_count=0;
         player[i].walk_count=0;
         player[i].RBI=0;
     }
     
 fp=fopen("baseball_player.dat","r");
while(  fscanf(fp,"%d %s %s %d %d %d %d",
&temp.number , temp.first_name , temp.last_name , &temp.at_bat , &temp.hit_count , &temp.walk_count , &temp.RBI ) ==7      )
     {
      strcpy( player[temp.number-1].first_name , temp.first_name );
      strcpy( player[temp.number-1].last_name  , temp.last_name  );
       player[temp.number-1].at_bat     +=temp.at_bat;
       player[temp.number-1].hit_count  +=temp.hit_count;
       player[temp.number-1].walk_count +=temp.walk_count;
       player[temp.number-1].RBI        +=temp.RBI;
     }
     fclose(fp);
     printf(" number   Playername        at_bat_ct  hit_ct  walk_ct  RBI    batting_average\n");
   for(int i=0;i<AMOUNT;i++)
      {
           player[i].batting_average =   player[i].hit_count*1.0 / player[i].at_bat;
          printf("%4d      %s·%-7s   \t%2d     \t%2d \t%2d \t%2d \t   %.2f\n",i+1 , player[i].first_name , player[i].last_name ,
           player[i].at_bat , player[i].hit_count , player[i].walk_count , player[i].RBI , player[i].batting_average  );
  }          
    return 0;
}

data

在这里插入图片描述

result

数据全瞎编。。。在这里插入图片描述


7.

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

分析
(1) 程序开始时显示当前list中的book,并为每本书标注序列号,方便用户查找要修改的book,顺便得到library数组最后一个book的下标.
(2) 询问用户是要add还是要modify (两者对文件的修改模式不同,add是文件末尾加,modify是全删掉重新写)
(3) 错误纠正:list为空提示不可modify,list全满提示不可add book,要求用户只能输入a,m和q(退出)
(4) 如果输入a就打开add_book函数,如果是m就打开modify_book函数
(5) add_book函数和书上相同
(6)modify函数通过序列号查找要处理的book,选择修改book信息或者直接删除该book,如果是改这条book某一信息会循环提示要不要改其他项,如果delete则直接跳出循环询问下一条要处理的book,如果输入-1,表示不再修改,退出modify函数
(7)循环提问接下来打算add还是modify,输入q来结束程序

重点一是add函数和modify函数运行结束后,唯一的工作区library数组要实时更新其中的book内容和最后一本book的下标位置,二是将更新内容实时写入文件

code

/* booksave.c -- saves structure contents in a file */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXTITL  40
#define MAXAUTL  40
#define MAXBKS   10             /* maximum number of books */
//结构说明
struct book {                   /* set up book template    */
    char title[MAXTITL];
    char author[MAXAUTL];
    float value;
};
//函数声明
char * s_gets(char * st, int n);
int add_book(int count,int n,struct book library[]);
int modify_book(int count,int n,struct book library[]);
void add_or_modify(int count,struct book library[]);

/*library数组是modify或add函数的workstation,任何对文件的修改都应该是在数组中改掉再传入文件,
对于add文件,只需把后加入数组的book用a+b模式添加到文件末尾即可,
对于modify文件,需要用w+b模式清除文件内容,将re-order过的book存入文件*/
int main(void)
{
    struct book library[MAXBKS]; /* array of structures     */
    int count=0;
    FILE *fp;
    fp=fopen("book.dat","rb"); //打开文件,show contents
     rewind (fp);
     while(  count<MAXBKS  &&  fread( &library[count] , sizeof(struct book) , 1 , fp ) ==1     )
     {
            if(count==0)
            puts("Current contens:");
            printf("%d. %s by %s: $%.2f\n", count+1 , library[count].title , library[count].author , library[count].value);
            count++;
      }
     fclose(fp);  //另一个作用是告诉add_or_modify函数现存Book数量,该函数中若满了提示不能添加,空的提示不能修改
     
    add_or_modify(count,library);
    
   
}    
   
//先选add还是modify,然后进入add或modify函数
void add_or_modify(int count,struct book library[])
{ 
    char choose;      //让用户选择是添加book还是修改book
    printf("What do you want to do?\n");
    printf("Enter 'm' to modify  the book information or 'a' to add the book\n");
    printf("Enter 'q' to quit\n");
while(       scanf("%c",&choose)==1 && choose!='q'   )
    {
         printf("Your choice is %c\n",choose);
         while(  getchar()!='\n'  )
              continue;         //清除scanf输入的回车符对add()或modify()函数的影响
              
         if( choose!='a'  && choose!='m')
            {
                printf("Input error , please input 'a' to add , 'm' to modify , 'q' to quit.\n");
                continue;
            }
         else if(  choose=='a'  &&  count==MAXBKS  ) //如果library已满而用户想add:
             { 
               printf("The library is filled, you can only modify the book information.\n");
               printf("Choose again:\n");
               continue;
             }
         else if ( choose=='m'  &&  count==0 )//如果library为空用户却想修改:
             {
               printf("The library is empty, you can only add the book .\n");
               printf("Choose again:\n");
               continue;
             }
         else if (  choose=='a'  &&  count !=MAXBKS  )//写入模式
                count=add_book(count,MAXBKS,library);
         else if ( choose=='m'  &&  count!=0 )        //修改模式
                count=modify_book(count,MAXBKS,library);
        //无论是add还是modify,结束函数时都应当把数组内容写入文件并关闭文件
         printf("\nAny other operation?\n");
        }   
            printf("Bye!\n");
}

int modify_book(int count,int n,struct book library[])
 {
  //read+ binary模式打开文件
     FILE *modi;
     char sel;
     int number;
     int delet[MAXBKS]={0};
     struct book copy[MAXBKS];
     modi = fopen("book.dat","w+b");
     
     printf("\nPlease select a book number:(-1 to finish modify library)\n");//用户用-1停止选择book,退出modify函数
     
     while(    scanf("%d",&number)==1  &&  number>0   )
       { 
           
           while(   getchar()!='\n'  )//clean 
                 continue;
                 
           if (number>count+1)//输入的数若大于现存book的最大序号,提示重新输入
              {
                 printf("%d book in list, input number again\n",count+1);
                 continue;
              }
              
           printf("What do you want to do:\n");   //show menu
           printf("a)delete book from library     b)modify book title\n");
           printf("c)modify book author           d)modify book price\n");
           printf("(Enter 'q' to quit)\n");
           
          while    (  scanf("%c",&sel)==1  &&   sel!='q'  )//用户用q退出对该条book的修改
            {
                
                 while(   getchar()!='\n'  )//clean 
                 continue;
                 
               if(   strchr("abcd",sel)==NULL     )
                   {
                      printf("Input error, please select from 'a' , 'b' , 'c' , 'd'.\n" );
                      continue;        //提示输入错误并重新输入操作选项
                   }
               if ( sel=='d' )
                   {
                       printf("Previous price is %.2f.\n" , library[number-1].value);
                       printf("New price:\n");
                       scanf("%f", &library[number-1].value );
                       printf("Price has been changed to %.2f.\n", library[number-1].value  );
                        while(   getchar()!='\n'  )//clean 
                           continue;
                    }
               if ( sel=='c' )
                   {
                       printf("Previous author is %s\n" , library[number-1].author);
                       printf("New author:\n");
                       s_gets(library[number-1].author,MAXAUTL);
                       printf("Author has been changed to %s.\n",  library[number-1].author );
                    }
               if ( sel=='b' )
                   {
                       printf("Previous title is %s\n" , library[number-1].title);
                       printf("New title:\n");
                       s_gets(library[number-1].title,MAXTITL);
                       printf("title has been changed to %s.\n",   library[number-1].title  );  
                    }
               if ( sel=='a' )
                   {
                       delet[number-1]=1;
                     printf("Book %d in list has been marked to remove\n",number);  
                     break;
                       //如果是选的a(delete该book),则直接跳出循环(对title,author,price的修改选择),重新选择book
                    }
             
                printf("Continue operate on book %d ?(a,b,c,d to modify or q to quit)\n",number);//如果选的是修改member内容(bcd),继续在循环内询问用户是否继续modify
            }
                fflush(stdin);//若一开始选择的是b,c,d;最后输入q来退出对该条book的修改,会在q后得到一个换行符
                printf("New book to modify?(-1 to exit)\n"); 
       }
               fflush(stdin);//同理,清除输入-1(结束对book的选择)带来的换行符
           printf("Modify finished.\n");
         fflush(stdin);           
          
        //写入file(擦除所有旧数据) 
             int file_count=0;
           for(int i=0;i<count;i++)
           {
               if(delet[i]==0)
             { copy[file_count]=library[i];//把所有没有mark上delete的结构变量写入copy数组,再将copy抄入file
                file_count++;}
           }
            printf("Show contents:\n");
         for (  int index=0 ; index < file_count ;  index++   )
           {  
               printf( " %d. %s by %s: $ %.2f\n", index+1, 
                 copy[index].title,  copy[index].author, copy[index].value);
                 library[index]=copy[index];
            }                
           fwrite( &library[0] , sizeof(struct book) , file_count , modi);
            fclose(modi);
            return file_count; 
//如果删除了若干条book,book数量count会发生变化,要反馈给主函数,因为add和modify函数涉及对library数组做操作,应当及时更新count
 }
 
 
 
//将存book的数组地址library传递给函数,告知函数该library数组第一个空位置(下标为count)
int add_book(int count,int n,struct book library[])

{
   //从library数组的最后一个record末尾接着数序号
    int count_proceed=count;
    //打开文件
    FILE *pbook;
   pbook = fopen("book.dat","a+b");
   printf("Please add new book title ");
   printf("(press [Enter] in a new line to quit):\n");
   
   //写入book数据
   while(  count_proceed < n   &&  s_gets( library[count_proceed].title , MAXTITL ) != NULL  
                && library[count_proceed].title[0]!='\0'         )//若library被写满,或者用户输入回车,则结束add book
        
         {
              printf("Now enter the author\n");
               s_gets(  library[count_proceed].author , MAXAUTL );
               printf("Now enter the value:\n");
               scanf("%f" ,  &library[count_proceed].value);
                fflush(stdin);
               count_proceed++;
               if (count_proceed<n)
                printf("Next title:\n");//循环写入书名,作者,价格
         }  
         
         printf("Finish add.\n");
         //显示内容并将数组写回文件
         printf("\nShow contents:\n");
         for (  int index=0 ; index < count_proceed ;  index++   )
           {  
               printf( " %d. %s by %s: $ %.2f\n", index+1, 
                 library[index].title,  library[index].author,  library[index].value);   
            }                               
//从library数组 进入函数之前的位置count开始,到最后结束时的位置count_proceed结束。一次性把数据全写入file
             fwrite( &library[count] , sizeof(struct book) , count_proceed-count , pbook);
              fclose(pbook);
              return count_proceed;
          
}
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');   // look for newline
        if (find)                  // if the address is not NULL,
            *find = '\0';          // place a null character there
        else
            while (getchar() != '\n')
                continue;          // dispose of rest of line
    }
    return ret_val;
}

result

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


8.

巨人航空公司的机群由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)。

code

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NAME_SIZE 30
#define SEAT_SIZE 12
struct booking {
         int seat;
        int  empty;
        char first_name[NAME_SIZE];
        char last_name[NAME_SIZE];
};
char * s_gets(char *str , int n);
void show_menu(void);
void show_list(struct booking record[]);
void choose(  struct booking book_system[]    );
void count_empty(   struct booking record[]  ,  int n  );
void show_empty(  struct booking record[]  ,  int n  );
void show_alpha_list(  struct booking record[]  ,  int n );
void assign(   struct booking record[]  ,  int n   );
void delete_assign(struct booking record[]  ,  int n );
void quit(  struct booking record[]  );


int main()
  {
    struct booking book_system[12];
    FILE *fp;
    //用if条件句判断航班信息有没有首次录入文件,如果没有,第一次要初始化航班座位号和empty flag.
    if(  (  fp=fopen("air.dat","rb")  )==NULL  )//打不开文件就不用关闭了
      {
          for (int i=0;i<SEAT_SIZE;i++)
           {
               book_system[i].seat=i+1;
               book_system[i].empty=1;
           }
      }
     else 
       {
           fread( book_system,  sizeof(struct booking) , SEAT_SIZE , fp);
            fclose(fp);
       }
      show_list(book_system);
    show_menu();
    choose(book_system);
    return 0;
}
void show_list(struct booking record[])
{
     for(int i=0;i<SEAT_SIZE;i++)
            {
                if(record[i].empty==0)
                  printf("%s %s - seat %d\n",record[i].first_name , record[i].last_name , record[i].seat);
            }
          printf("\n");  
}
void choose(struct booking book_system[])
 {
     char sel;
     scanf("%c",&sel);
     while (  sel!='f'  && sel!='F' )//只要输入的不是quit
       {
           fflush(stdin);
           if  (    strchr("abcdeABCDE",sel)==NULL       )
                  {
                         printf("Input error,please input a-e or A-E");
                         continue; 
                  }
         switch (sel)
                { 
                  case 'a':
                  case 'A': count_empty(book_system,SEAT_SIZE);
                            break;
                  case 'b':
                  case 'B': show_empty(book_system,SEAT_SIZE);
                            break;
                  case 'c':
                  case 'C': show_alpha_list(book_system,SEAT_SIZE);
                            break;
                  case 'd':
                  case 'D': assign(book_system,SEAT_SIZE);
                            break;
                  case 'e':
                  case 'E': delete_assign(book_system,SEAT_SIZE);
                            break;
                }
            
                printf("\nContinue to operate?\n");
               show_menu();
               scanf("%c",&sel);
       }
       //sel=f or F时:
           printf("Bye!\n");
           quit(book_system);
 }
 void quit(struct booking record[])
 {
      FILE *fpp;
    fpp=fopen("air.dat","wb");
    fwrite( record, sizeof(struct booking) , SEAT_SIZE , fpp );
    fclose(fpp);
 }
void delete_assign(struct booking record[]  ,  int n )
 {
      int number_delet;
      char confirm;
     printf("\n");
     show_list(record);
     printf("\n");
       printf("Iuput the seat number to cancel the reserve (Enter -1 to quit):\n");
             while( scanf("%d",&number_delet)==1  && number_delet>0  )
                { 
                    fflush(stdin);
                  if(number_delet>n)
                      {
                        puts("This plane has %d seat, please reenter:");
                        continue;
                      }
                  if(  record[number_delet-1].empty==1  )
                      {
                         puts("seat %d is a empty seat, please reenter:");
                         continue;
                      }  
            //提示该位置的乘客名字,以免错误删除          
                     printf("Seat %d is reserved for %s %s,",
         number_delet , record[number_delet-1].first_name , record[number_delet-1].last_name);
                 printf(" Are you sure to delete it?(Y or N):\n");
                while(  scanf("%c",&confirm)==1  &&   strchr( "yYnN",confirm)==NULL   )
                    {
                        fflush(stdin);
                     puts("Input error, please input Y to cofirm delete or N to change the seat");
                       continue;
                    }
                    if( confirm=='n'  || confirm=='N'        )
                        printf("Select error, please reenter the seat:\n");
                    else if ( confirm=='y'  || confirm=='Y' )
                        {
                         record[number_delet-1].empty=1;
                         record[number_delet-1].first_name[0]='\0';
                         record[number_delet-1].last_name[0] ='\0';
                         printf("Reservation for seat %d has been cancelled.\n",number_delet);
                        }
                    puts("Input another seat to cancel book or input -1 to end the operation:");
                }   
                fflush(stdin);
                puts("Finish delete\n");
                show_list(record);
  }
void assign(   struct booking record[]  ,  int n   )
 {
      show_empty(record,n);
      int number;
      printf("Please select a seat number(-1 to quit assign)\n");
        while( scanf("%d",&number)==1 && number>0 )
           {
             fflush(stdin);
              if ( number>12 )//如果number大于飞机座位上限
                 {
                     printf("This plane has %d seats, please reenter:\n",n);
                     continue;
                 }
             if ( record[number-1].empty != 1 ) //如果输入的是一个被占的座位,需要重新输入
                { 
                    printf("This seat is occupied, please choose a empty one:\n");
                    continue;
                }
              record[number-1].empty=0;  //提示该位置已被占
              printf("Please Enter your first name:\n");
                s_gets(  record[number-1].first_name ,  NAME_SIZE   );
              printf("And last name:\n");
                s_gets(  record[number-1].last_name ,  NAME_SIZE   );
              printf("Enter the seat number to continue booking or input -1 to quit.\n");    
           }  
           fflush(stdin);
           printf("Assign finished\n\n");
          show_list(record);
 }
void count_empty(   struct booking record[]  ,  int n  )
 {
      int count=0;
      for(int i=0;i<n;i++)
        {
            if ( record[i].empty == 1 )
                 count++;
        }
        printf("%d empty seat%s\n",count, (count>1)?"s.":".");
 }
void show_empty(  struct booking record[]  ,  int n  )
 {
   printf("seat available:\n");
    for(int i=0;i<n;i++)
     {
         if( record[i].empty == 1 )
          printf("%3d ",record[i].seat);
     }
     printf("\n");
 }
void show_alpha_list(  struct booking record[]  ,  int n )
 {
   struct booking *str[SEAT_SIZE];
   struct booking *temp;
   int copy_count=0;
   int j,k;
   for(int i=0;i<SEAT_SIZE;i++)
        {
          if(   record[i].empty== 0  )
              {
                  str[copy_count]=&record[i];
                  copy_count++;
              }
        }
    for (j=0;j<copy_count-1;j++)
         {
             for(k=j+1;k<copy_count;k++)
                {
                    if( strcmp(str[j]->first_name,str[k]->first_name)>0 )
                      {
                         temp=str[j]; 
                         str[j]=str[k];
                         str[k]=temp;
                      }
                }
         }
        
         for(int x=0;x<copy_count;x++)
          {
        printf("%s %s - seat %d\n", str[x]->first_name , str[x]->last_name , str[x]->seat);
          }
 }
void show_menu(void)
 {
    printf("To choose a function, enter its letter label:\n");
    printf("a) Show number of empty seats        b) Show list of empty seats\n");
    printf("c) Show alphabetical list of seats   d) Assign a customer to a seat assignment\n");
    printf("e) Delete a seat assignment          f) Quit\n");
}
char * s_gets(char *str , int n)
{
    char *find;
    char *ret_val;
    ret_val=fgets(str,n,stdin);
      if(ret_val)
       {
           find=strchr(str,'\n');
             if (find)
                *find='\0';
             else
                while(getchar()!='\n')
                continue;
       }
       return  ret_val;
}

result

function a&b

function c&d
在这里插入图片描述
function e&f
在这里插入图片描述


9.

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

code

对确认座位分配的个人理解:为给座位上锁,当用户想删除该位置上的乘客时进行阻止(指明确认状态),在confirm函数中可以对座位上锁或解锁。为此本人在结构中添加了一个lock flag.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NAME_SIZE 30
#define SEAT_SIZE 12
#define NUMBER_LENTH 4
struct booking {int seat;  int  empty;  char first_name[NAME_SIZE];  char last_name[NAME_SIZE];  int lock };
//航班间选择函数
void welcome_flight_menu(void);
void get_flight_open_file( char sel[] , FILE *fp , struct booking flight[] );
void open_file_copy_arr_102( FILE *fp,struct booking book_system[]);
void open_file_copy_arr_311( FILE *fp,struct booking book_system[]);
void open_file_copy_arr_444( FILE *fp,struct booking book_system[]);
void open_file_copy_arr_519( FILE *fp,struct booking book_system[]);

//航班内处理函数
void show_menu(void);
void choose(struct booking book_system[] , char number[] , FILE *fp  );
void count_empty(   struct booking record[]  ,  int n  );
void show_empty(  struct booking record[]  ,  int n  );
void show_alpha_list(  struct booking record[]  ,  int n );
void assign(   struct booking record[]  ,  int n   );
void delete_assign(struct booking record[]  ,  int n );
void confirm(struct booking record[]);
//通用函数
char * s_gets(char *str , int n);
void show_list(struct booking record[]);

int main()
{
    struct booking flight[SEAT_SIZE];
    char sel[NUMBER_LENTH];//接收航班号
    FILE *fp;
   
    welcome_flight_menu();
    
    //输入航班号,回车结束顶层菜单,结束程序
    while(     s_gets(sel,NUMBER_LENTH)!=NULL   &&   sel[0]!='\0'  )
      {
          
           if( strstr("102_311_444_519_a_b_c_d",sel)==NULL)
          {
            printf("Input error, you should input the flight number");
            printf(" (like 102) or corresponding letter (like a).\n");
            puts("reenter:");
            continue;
          }
          
      //rb模式打开对应航班文件,将乘客信息读入工作数组flight中,并把航班号sel从字母改为编号,关闭文件          
      get_flight_open_file(  sel , fp , flight );

      //展示读到工作数组flight中的乘客信息     
      printf("Here is the passenger list of flight %s:\n",sel);
      show_list(flight); 
      
      //提示用户可以显示空位置数量和座位号码,添加删除乘客等等。。。。。。
      //choose函数选择要执行的任务,最后将更新完的内容写入file并关闭file
      show_menu(); 
      choose( flight , sel , fp );
      show_list(flight);
      
      //wb模式写入对应file
       if(  strcmp(sel,"102") ==0 ) //此处想写成一个函数,传递和关闭文件指针,但是各种bug
          fp=fopen("air102.dat","wb");
      else if ( strcmp(sel,"311") ==0 )
          fp=fopen("air311.dat","wb");
      else if ( strcmp(sel,"444") ==0 )
          fp=fopen("air444.dat","wb");
      else if ( strcmp(sel,"519") ==0 )
          fp=fopen("air519.dat","wb");   
       fwrite( flight , sizeof (struct booking) , SEAT_SIZE ,fp );
       fclose(fp);
      
      printf("Switch to other flight?\n");
       }
       
      printf("Good bye!");
    return 0;
}

//通用函数
void show_list(struct booking record[])
 {
     for(int i=0;i<SEAT_SIZE;i++)
            {
                if(record[i].empty==0)
                  printf("%s %s - seat %d\n",record[i].first_name , record[i].last_name , record[i].seat);
            }
          printf("\n");  
}
char * s_gets(char *str , int n)
 {
    char *find;
    char *ret_val;
    ret_val=fgets(str,n,stdin);
      if(ret_val)
       {
           find=strchr(str,'\n');
             if (find)
                *find='\0';
             else
                while(getchar()!='\n')
                continue;
       }
       return  ret_val;
}

//航班选择函数
void welcome_flight_menu(void)
 {
     printf("Welcome, Giant Airplane company has 4 flight daily:\n");
    printf("a.flight 102    b.flight 311\nc.flight 444    d.flight 519\n"); 
    printf("Please select the Flight number or press [Enter] to quit:\n");
}
void get_flight_open_file(  char sel[] , FILE *fp , struct booking flight[] )
 {
        if (   strcmp( "102" , sel )==0   ||   strcmp( "a" , sel )==0   )
            {
               open_file_copy_arr_102( fp , flight );
               strcpy(sel,"102");
            }
          else if (    strcmp( "311" , sel )==0   ||   strcmp( "b" , sel )==0  )
            {
               open_file_copy_arr_311( fp , flight );
               strcpy(sel,"311");
            }
          else if (    strcmp( "444" , sel )==0   ||   strcmp( "c" , sel )==0  )
            {
               open_file_copy_arr_444( fp , flight ); 
                strcpy(sel,"444");
            }
          else if (    strcmp( "519" , sel )==0   ||   strcmp( "d" , sel )==0  )
            {
               open_file_copy_arr_519( fp , flight );
                strcpy(sel,"519");
            }
}
void open_file_copy_arr_102( FILE *fp,struct booking book_system[])
 {
    
//如果当前航班文件为空,无法读取,就要初始化工作数组:flight , 为数组标上seat序号和empty flag=1    
    if (  ( fp=fopen("air102.dat","rb") )==NULL )
      {
           for (int i=0;i<SEAT_SIZE;i++)
            {
               book_system[i].seat=i+1;
               book_system[i].empty=1;
               book_system[i].lock=0;
            }
      }        
     else //如果文件非空
         {
            fread( book_system,  sizeof(struct booking) , SEAT_SIZE , fp);
            fclose (fp);
         }
}
void open_file_copy_arr_311( FILE *fp,struct booking book_system[])
 {
     if (  ( fp=fopen("air311.dat","rb") )==NULL )
      {
           for (int i=0;i<SEAT_SIZE;i++)
            {
               book_system[i].seat=i+1;
               book_system[i].empty=1;
               book_system[i].lock=0;
            }
      }        
     else //如果文件非空
         {
            fread( book_system,  sizeof(struct booking) , SEAT_SIZE , fp);
            fclose (fp);
         }
}
void open_file_copy_arr_444( FILE *fp,struct booking book_system[])
 {
    if (  ( fp=fopen("air444.dat","rb") )==NULL )
      {
           for (int i=0;i<SEAT_SIZE;i++)
            {
               book_system[i].seat=i+1;
               book_system[i].empty=1;
               book_system[i].lock=0;
            }
      }        
     else //如果文件非空
         {
            fread( book_system,  sizeof(struct booking) , SEAT_SIZE , fp);
            fclose (fp);
         }
}
void open_file_copy_arr_519( FILE *fp,struct booking book_system[])
 {
     if (  ( fp=fopen("air519.dat","rb") )==NULL )
      {
           for (int i=0;i<SEAT_SIZE;i++)
            {
               book_system[i].seat=i+1;
               book_system[i].empty=1;
               book_system[i].lock=0;
            }
      }        
     else //如果文件非空
         {
            fread( book_system,  sizeof(struct booking) , SEAT_SIZE , fp);
            fclose (fp);
         }
}

//航班内处理函数

void show_menu(void)
 {
    printf("To choose a function, enter its letter label:\n");
    printf("a) Show number of empty seats        b) Show list of empty seats\n");
    printf("c) Show alphabetical list of seats   d) Assign a customer to a seat assignment\n");
    printf("e) Delete a seat assignment          f) Confirm a seat\n");
    printf("g) Go back to top menu\n");
}
void choose(struct booking book_system[] , char number[] , FILE *fp  )
 {
     char sel;
     scanf("%c",&sel);
     while (  sel!='g'  && sel!='G' )//只要输入的不是quit
       {
           fflush(stdin);
           if  (    strchr("abcdefABCDEF",sel)==NULL       )
                  {
                         printf("Input error,please input a-f or A-F");
                         continue; 
                  }
         switch (sel)
                { 
                  case 'a':
                  case 'A': count_empty(book_system,SEAT_SIZE);
                            break;
                  case 'b':
                  case 'B': show_empty(book_system,SEAT_SIZE);
                            break;
                  case 'c':
                  case 'C': show_alpha_list(book_system,SEAT_SIZE);
                            break;
                  case 'd':
                  case 'D': assign(book_system,SEAT_SIZE);
                            break;
                  case 'e':
                  case 'E': delete_assign(book_system,SEAT_SIZE);
                            break;
                  case 'f':
                  case 'F': confirm(book_system);
                            break;
                }
            
                printf("\nContinue to operate?\n");
               show_menu();
               scanf("%c",&sel);
       }
       //sel=g or G时:
           printf("Quit operating flight %s !\n",number);
          fflush(stdin);
 }
void count_empty(   struct booking record[]  ,  int n  )
 {
      int count=0;
      for(int i=0;i<n;i++)
        {
            if ( record[i].empty == 1 )
                 count++;
        }
        printf("%d empty seat%s\n",count, (count>1)?"s.":".");
 }
void show_empty(  struct booking record[]  ,  int n  )
 {
   printf("seat available:\n");
    for(int i=0;i<n;i++)
     {
         if( record[i].empty == 1 )
          printf("%3d ",record[i].seat);
     }
     printf("\n");
 }
void show_alpha_list(  struct booking record[]  ,  int n )
 {
   struct booking *str[SEAT_SIZE];
   struct booking *temp;
   int copy_count=0;
   int j,k;
   for(int i=0;i<SEAT_SIZE;i++)
        {
          if(   record[i].empty== 0  )
              {
                  str[copy_count]=&record[i];
                  copy_count++;
              }
        }
    for (j=0;j<copy_count-1;j++)
         {
             for(k=j+1;k<copy_count;k++)
                {
                    if( strcmp(str[j]->first_name,str[k]->first_name)>0 )
                      {
                         temp=str[j]; 
                         str[j]=str[k];
                         str[k]=temp;
                      }
                }
         }
        
         for(int x=0;x<copy_count;x++)
          {
        printf("%s %s - seat %d\n", str[x]->first_name , str[x]->last_name , str[x]->seat);
          }
 }
void assign(   struct booking record[]  ,  int n   )
 {
      show_empty(record,n);
      int number;
      printf("Please select a seat number(-1 to quit assign)\n");
        while( scanf("%d",&number)==1 && number>0 )
           {
             fflush(stdin);
              if ( number>SEAT_SIZE )//如果number大于飞机座位上限
                 {
                     printf("This plane has %d seats, please reenter:\n",n);
                     continue;
                 }
             if ( record[number-1].empty != 1 ) //如果输入的是一个被占的座位,需要重新输入
                { 
                    printf("This seat is occupied, please choose a empty one:\n");
                    continue;
                }
              record[number-1].empty=0;  //提示该位置已被占
              printf("Please Enter your first name:\n");
                s_gets(  record[number-1].first_name ,  NAME_SIZE   );
              printf("And last name:\n");
                s_gets(  record[number-1].last_name ,  NAME_SIZE   );
              printf("Enter the seat number to continue booking or input -1 to quit.\n");    
           }  
           fflush(stdin);
           printf("Assign finished\n\n");
          show_list(record);
 }
void delete_assign(struct booking record[]  ,  int n )
 {
      int number_delet;
      char confirm;
     show_list(record);
     printf("Iuput the seat number to cancel the reserve (Enter -1 to quit):\n");
             while( scanf("%d",&number_delet)==1  && number_delet>0  )
                { 
                    fflush(stdin);
                  if(number_delet>n)
                      {
                        puts("This plane has %d seat, please reenter:");
                        continue;
                      }
                  if(  record[number_delet-1].empty==1  )
                      {
                         puts("seat %d is a empty seat, please reenter:");
                         continue;
                      }  
                  if (   record[number_delet-1].lock==1      )  
                       {
                         puts("This seat has been confirmed, please choose other seat:");
                         continue;
                      }  
            //提示该位置的乘客名字,以免错误删除          
                     printf("Seat %d is reserved for %s %s,",
         number_delet , record[number_delet-1].first_name , record[number_delet-1].last_name);
                 printf(" Are you sure to delete it?(Y or N):\n");
                while(  scanf("%c",&confirm)==1  &&   strchr( "yYnN",confirm)==NULL   )
                    {
                        fflush(stdin);
                     puts("Input error, please input Y to cofirm delete or N to change the seat");
                       continue;
                    }
                    if( confirm=='n'  || confirm=='N'        )
                        printf("Select error, please reenter the seat:\n");
                    else if ( confirm=='y'  || confirm=='Y' )
                        {
                         record[number_delet-1].empty=1;
                         record[number_delet-1].first_name[0]='\0';
                         record[number_delet-1].last_name[0] ='\0';
                         printf("Reservation for seat %d has been cancelled.\n",number_delet);
                        }
                    puts("Input another seat to cancel book or input -1 to end the operation:");
                }   
                fflush(stdin);
                puts("Finish delete\n");
                show_list(record);
  }
void confirm(struct booking record[])
 {
     int seat_number;
     char ans;
     printf("Which seat do you want to confirm or de-confirm(-1 to quit):\n");
      while (scanf("%d",&seat_number)==1  && seat_number>0)
       {  
            fflush(stdin);
           if ( seat_number>SEAT_SIZE)
             {
               printf("Input error, the plane has %d seats\n",SEAT_SIZE);
               printf("reenter or(-1 to quit):\n");
               continue;
             }
           if ( record[seat_number-1].lock==1)
             {
                 printf("Seat %d confirmed, do you want to unlock it?(y or n)\n",seat_number);
                 
                 while( scanf("%c",&ans)==1 && strchr("yYnN",ans)==NULL )
                  {   
                      fflush(stdin);
                      printf("Only receive y to unlock it or n to cancel operation:\n");
                      continue;
                  }
                  if(ans=='y' || ans=='Y')
                  {
                      record[seat_number-1].lock=0;
                      printf("Seat %d has been unlocked\n",seat_number);
                  }
                  else
                    printf("Unlock cancelled\n");
             }
          else if ( record[seat_number-1].lock==0)
             {
                 printf("Seat %d hasn't been locked, do you want to confirm it?(y or n)\n",seat_number);
                 while( scanf("%c",&ans)==1 && strchr("yYnN",ans)==NULL )
                  {
                      fflush(stdin);
                      printf("Only receive y to lock it or n to cancel operation:\n");
                      continue;
                  }
                  if(ans=='y' || ans=='Y')
                  {
                      record[seat_number-1].lock=1;
                      printf("Seat %d has been confirmed to lock\n",seat_number);
                  }
                  else
                   printf("Cancel confirm\n");
             }
             fflush(stdin);
             printf("Choose an other seat or -1 to quit:\n");
       }
       fflush(stdin);
       printf("Confirm finished\n");
}

result

用confirm函数锁定座位(也可解除锁定)

在这里插入图片描述

delete函数提示该座位不可删除

在这里插入图片描述

切换航班号

在这里插入图片描述

10.

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

code

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define AMOUNT 4
double half(double x);
double square(double x);
double cube(double x);
void show_menu();

int main()
{
 double (*pf[AMOUNT])(double x)={half,square,cube,sqrt};  
 double input;
 double output;
 char select;
 show_menu();
    while( scanf("%c",&select)==1 && select!='q')
  {
      
    if (select>'d' ||select<'a')
        {
            printf("Input error,please enter a,b,c,d,q to choose:\n");
            while(getchar()!='\n')
              continue;
            continue;
        }
    else 
        { printf("Next, input a value:\n");
          scanf("%lf",&input);
           output= pf[select-'a'](input);
            printf("The answer = %.2lf\n",output);
        }
       printf("Select function again?\n");
       while(getchar()!='\n')
              continue;
  }printf("Bye!\n");
    return 0;
}
void show_menu()
{
    printf("Please select a function(q to quit):\n");
    printf("a) half the input    b)double the input\n");
    printf("c) triple the input  d)squareroot the input\n" );
    printf("q) quit\n");
}
double half(double x){return x/2;}
double square(double x){return x*x;}
double cube(double x){return x*x*x;}

result

在这里插入图片描述


11.

编写一个名为transform()的函数,接受4个参数:内含double类型数据的源数组名、内含double类型数据的目标数组名、一个表示数组元素个数的int类型参数、函数名(或等价的函数指针)。transform()函数应把指定函数应用于源数组中的每个元素,并把返回值储存在目标数组中。
例如:transform(source, target, 100, sin);该声明会把target[0]设置为sin(source[0]),等等,共有100个元素。在一个程序中调用transform()4次,以测试该函数。分别使用math.h函数库中的两个函数以及自定义的两个函数作为参数。

code

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define SIZE 7
double cube(double x);
double square(double x); 
void transform(double * source,double * target ,int n , double (*fp)(double x)   );
void show_contents(int n,double *arr);
int main()
{
   double source[SIZE]={0.5 , -1.1 , 2.3456 , -5.13 , 10.0 , 8.8, -4.2 };
   
   double target[SIZE];
   printf("Show source array[%d]:\n",SIZE);
           show_contents(SIZE,source);
   printf("Show the fab :\n");
     transform(source,target,SIZE,fabs);
           show_contents(SIZE,target);
   printf("Show the ceil :\n");
     transform(source,target,SIZE,ceil);
           show_contents(SIZE,target);
   printf("Show the cube :\n");
     transform(source,target,SIZE,cube);
           show_contents(SIZE,target);
   printf("Show the square :\n");
     transform(source,target,SIZE,square);
           show_contents(SIZE,target);
   
    return 0;
}
void transform(double * source,double * target ,int n , double (*fp)(double x)   )
{
    for (int i=0;i<n;i++)
       *(target+i) =  fp( *(source+i) );
}
void show_contents(int n,double *arr)
{
     for (int i=1;i<=n;i++)
         printf("%12.4lf ", *(arr+i-1) );
         
        printf("\n");
}
double cube(double x)
{ return x*x*x;}
double square(double x)
{ return x*x;}

result

在这里插入图片描述


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值