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