这是典型的结构嵌套的使用。
//基于第八题的结构嵌套使用(四架飞机,每架相同的配置)。
#include<stdio.h>
#include<stdlib.h>
#define FLIGHT 4
#define SEAT 12
void read_file(struct flight *,char *);
void load_data(struct flight *);//默认数据。
int choose_flight(void);
int choose_command(struct flight *);
void write_file(struct flight *,char *);
void show_number_empty(struct seat *);
void show_list_empty(struct seat *);
void show_list(struct seat *);
void assign_seat(struct seat *);
void delete_seat(struct seat *);
void confirm_seat(struct seat *);
struct seat
{
int number;
int assign;
char lastname[20];
char firstname[20];
};
struct flight
{
int number;
struct seat seats[SEAT];//结构嵌套。
};
struct flight flights[4]=//初始化4个航班的结构数组。
{
{102},
{311},
{444},
{519}
};
int main(void)
{
int n;
read_file(flights,"seat.dat");
while(1)
{
n=choose_flight();
if(n<0 || n>=FLIGHT)//n=0123
break;
while(choose_command(&flights[n]))//返回是个1.这就是choose_command()函数返回值使int类型的原因。
continue;
}
write_file(flights,"seat.dat");
puts("Quit");
return 0;
}
void read_file(struct flight *p,char *filename)//读取文件操作。
{
FILE *pseats;
if((pseats=fopen(filename,"r+b"))==NULL)
{
printf("Can't open %s file,So load default data.\n",filename);//首次打开时显示这一句,因为没有数据。也因此也不能有exit(1),否则会直接退出程序。
load_data(p);//载入默认的数据。使程序更友好。
}
else
{
rewind(pseats);//文件起始位置。
while(fread(p,sizeof(struct flight),FLIGHT,pseats)==1)
continue;
fclose(pseats);
printf("Read %s successfully!",filename);//第二次打开文件以后都会显示。
}
}
void load_data(struct flight *p)//载入默认的数据。
{
int i,j;
for(i=0;i<FLIGHT;i++)
for(j=0;j<SEAT;j++)
{
p[i].seats[j].number=i*100+j;
p[i].seats[j].assign=0;
}
}
int choose_flight(void)
{
char command[10];
printf("To choose a flight,enter lts letter label:\n");
printf("a) Flights 102\t valid number is 000 001 002 003 004 005 006 007 008 009 010 011\n");
printf("b) Flights 311\t valid number is 100 101 102 103 104 105 106 107 108 109 110 111\n");
printf("c) Flights 444\t valid number is 200 201 202 203 204 205 206 207 208 209 210 211\n");
printf("d) Flights 519\t valid number is 300 301 302 303 304 305 306 307 308 309 310 311\n");
printf("e) Quit\n");
gets(command);
switch(command[0])//清楚了多余输入。
{
case 'a': return 0;//int 返回值函数值的原因。使n=0123
case 'b': return 1;
case 'c': return 2;
case 'd': return 3;
default: return 4;
}
}
int choose_command(struct flight *p)
{
char command[10];
printf("Flight %d:\n",p->number);
printf("To choose a function,enter its letter label:\n");
printf("a) Show number of empty seats\n");
printf("b) Show list of empty seats\n");
printf("c) Show alphabetical list of seats\n");
printf("d) Assign a customer to a seat assignment\n");
printf("e) Delete a seat asignment\n");
printf("f) Confirm a seat assignment\n");
printf("g) Exit to the top-level menu\n");
gets(command);
switch(command[0])
{
case 'a': show_number_empty(p->seats);return 1;
case 'b': show_list_empty(p->seats);return 1;
case 'c': show_list(p->seats);return 1;
case 'd': assign_seat(p->seats);return 1;
case 'e': delete_seat(p->seats);return 1;
case 'f': confirm_seat(p->seats);return 1;//注意p->seats的表达式的意义。
default: return 0;
}
}
void show_number_empty(struct seat *p)//显示空位的个数。
{
int n=0,i;
for(i=0;i<SEAT;i++)
if(p[i].assign==0)
n++;
printf("There are %d empty seats.\n",n);
}
void show_list_empty(struct seat *p)//显示空位的标号信息。
{
printf("Empty seats:\n");
for(int i=0;i<SEAT;i++)
if(p[i].assign==0)
printf("Number %d\t%d\n",p[i].number,p[i].assign);
}
void show_list(struct seat *p)//显示位置的所有信息,number,assign,lastname,firstname。
{
printf("Seat list:\n");
for(int i=0;i<SEAT;i++)
{
printf("number %d \t assign %d\t",p[i].number,p[i].assign);
if(p[i].assign==1)
printf("Full %s %s\n",p[i].firstname,p[i].lastname);
else
printf("empty!\n");
}
}
void assign_seat(struct seat *p)//预约座位。
{
int number;
printf("Input the seat number:");
scanf("%d",&number);
while(getchar()!='\n')
continue;
for(int i=0;i<SEAT;i++)
if(p[i].number==number)
{
if(p[i].assign==1)
printf("No! %d seat is already assigned!\n",p[i].number);
else
{
printf("Input firstname of the holder:");
scanf("%s",p[i].firstname);
printf("Input lastname of the holder:");
scanf("%s",p[i].lastname);
while(getchar()!='\n')
continue;
p[i].assign=1;//订了位子计一。
printf("assign No.%d seat successfully!\n",p[i].number);
}
return ;//该句很重要,如果有符合的数字,那么就退出函数1,而不会打印出下一句无效的提示。
}
printf("%d is a invaild seat number!\n",number);
}
void delete_seat(struct seat *p)//删除定位。
{
int number;
printf("Input the seat number:");
scanf("%d",&number);
while(getchar()!='\n')
continue;
for(int i=0;i<SEAT;i++)
if(p[i].number==number)
{
if(p[i].assign==0)
printf("No.%d seat is already empty!\n",number);
else
{
p[i].assign=0;
printf("delete NO.%d seat successfully!\n",number);
}
return ;//功能如上。
}
printf("%d is a invalid seat number\n",number);
}
void confirm_seat(struct seat *p)//查询座位情况。
{
int number,i;
printf("Input the seat number:");
scanf("%d",&number);
while(getchar()!='\n')
continue;
for(i=0;i<SEAT;i++)
if(p[i].number==number)
{
if(p[i].assign==0)
printf("No.%d seat is empty!\n",number);
else
printf("No.%d seat is assigned! its holder is %s %s\n",p[i].firstname,p[i].lastname);
return ;
}
printf("%d is a invalid seat number\n");
}
void write_file(struct flight *p,char *filename)//写入文件。
{
FILE *pseats;
if((pseats=fopen(filename,"w+b"))==NULL)//先清空文件“w+b”.
{
printf("Can't open %s filename",filename);
exit(EXIT_FAILURE);
}
fwrite(p,sizeof(struct flight),FLIGHT,pseats);
fclose(pseats);
}
借鉴于原题例子。