第一题:重做复习题3但用月份名的拼写代替月份号(别忘了可以使用strcmp())。
解:可能是印刷错误,应该是重做复习题5
代码如下:
#include
#include
typedef struct month {
char name[10];
char na[3];
int days;
int monumb;
} MONTH;
int countdays(MONTH mon[],char m);
int main(void)
{
MONTH mon[12] = {
{"January","jan",31,1},
{"Febyuary","feb",28,2},
{"March","mar",31,3},
{"April","apr",30,4},
{"May","may",31,5},
{"June","jun",30,6},
{"July","jul",31,7},
{"August","agu",31,8},
{"September","sep",30,9},
{"October","oct",31,10},
{"November","nov",30,11},
{"December","dec",31,12},
};
char line[10];
int i;
int find = 0;
int m;
while(gets(line) != NULL && line[0] != '\0')
{
for(i = 0;i < 12;i++)
if(strcmp(mon[i].name,line) == 0)
{
find = 1;
break;
}
if(find)
{
m = mon[i].monumb;
break;
}
else
puts("wrong input,try again");
}
printf("%d days\n",countdays(mon,m));
return 0;
}
int countdays(MONTH mon[],char m)
{
int tdays = 0;
int i;
for(i = 0;i < m;i++)
tdays +=mon[i].days;
return tdays;
}
———————————————分割线—————————————————
第二题:编写一个程序。请求用户键入日、月、年。月份可以是月份号、月份名或月份缩写。然后程序返回一年中到给定日志包括这一天的总天数。
解:
代码如下:
#include
#include
#include
union month_n {
int m_n;
char m_c[10];
char m_s[3];
};
struct input {
int day_n;
union month_n mon_n;
int year_n;
};
struct months {
char name[10];
char na[3];
int day;
int mon_n;
};
int main(void)
{
struct months mons[12] = {
{"January","jan",31,1},
{"Febyuary","feb",28,2},
{"March","mar",31,3},
{"April","apr",30,4},
{"May","may",31,5},
{"June","jun",30,6},
{"July","jul",31,7},
{"August","agu",31,8},
{"September","sep",30,9},
{"October","oct",31,10},
{"November","nov",30,11},
{"December","dec",31,12}
};
struct input in;
int i;
int tdays = 0;
char line[10];
puts("Input the day:");
scanf("%d",&in.day_n);
while(getchar() != '\n');
puts("Input the month:");
if(scanf("%d",&in.mon_n.m_n))
{
if(!(in.mon_n.m_n > 0 && in.mon_n.m_n < 13))
{
puts("out of range!");
exit(1);
}
}
else
{
scanf("%s",line);
if(strlen(line) > 3)
{
strcpy(in.mon_n.m_c,line);
for(i = 0;i < 12;i++)
{
if(strcmp(mons[i].name,in.mon_n.m_c) == 0)
{
in.mon_n.m_n = i + 1;
break;
}
}
}
else if(strlen(line) == 3)
{
strcpy(in.mon_n.m_s,line);
for(i = 0;i < 12;i++)
{
if(strcmp(mons[i].na,in.mon_n.m_s) == 0)
{
in.mon_n.m_n = i + 1;
break;
}
}
}
}
puts("Input the year:");
scanf("%d",&in.year_n);
for(i = 0;i < in.mon_n.m_n - 1;i++)
tdays += mons[i].day;
tdays += in.day_n;
if(in.mon_n.m_n > 2 && in.year_n % 4 == 0)
tdays++;
printf("total %d days\n",tdays);
return 0;
}
———————————————分割线—————————————————
第三题:修改程序清单14.2中的书目列表程序,使它首先按照输入的顺序输出图书的描述,然后按照标题的字母升序输出图书的描述,最后按照value值的升序输出图书的描述。
解:
代码如下:
#include
#include
#define MAXTITL 40
#define MAXAUTL 40
#define MAXBKS 100
struct book {
char title[MAXTITL];
char author[MAXAUTL];
float value;
};
int main(void)
{
struct book library[MAXBKS];
int count = 0;
int index;
printf("Please enter the book title.\n");
printf("Press [enter] at the start of a line to stop.\n");
while(count < MAXBKS && gets(library[count].title) != NULL && library[count].title[0] != '\0')
{
printf("Now enter the author.\n");
gets(library[count].author);
printf("Now enter the value.\n");
scanf("%f",&library[count++].value);
while(getchar() != '\n');
if(count < MAXBKS)
printf("Enter the next title.\n");
}
if(count > 0)
{
printf("Here is the list of your books:\n");
for(index = 0;index < count;index++)
printf("%s by %s:$%.2f\n",library[index].title,library[index].author,library[index].value);
puts("");
if(count == 1)
printf("%s by %s:$%.2f\n",library[0].title,library[0].author,library[0].value);
char * ptr[MAXTITL];
char lib[count][MAXTITL];
char * temp;
int j;
for(index = 0;index < count;index++)
{
strcpy(lib[index],library[index].title);
ptr[index] = lib[index];
}
for(index = 0;index < count - 1;index++)
for(j = index + 1;j < count;j++)
if(strcmp(ptr[index],ptr[j]) > 0)
{
temp = ptr[index];
ptr[index] = ptr[j];
ptr[j] = temp;
}
if(count > 1)
for(index = 0;index < count;index++)
for(j = 0;j < count;j++)
if(strcmp(ptr[index],library[j].title) == 0)
printf("%s by %s:$%.2f\n",library[j].title,library[j].author,library[j].value);
}
else
printf("No books?Too bad.\n");
return 0;
}
———————————————分割线—————————————————
第四题:编写一个程序。按照下列要求,创建一个含有两个成员的结构模板:
a.第一个成员是社会保障号;第二个成员是一个含三个成员的结构。它的第一个成员是名,第二个成员是名和姓中间的名字,最后一个成员是姓。创建并初始化一个含有5个此类结构的数组。程序以下列行书输出数据:
Dribble,Flossie M. - 302039823
名和姓中间的名字只输出了它的第一个字母,后面加了一个据点。如果姓名中间的名字为空,那么它的第一个字母和据点都不会输出。写一个函数来实现输出,把结构数组传递给这个函数
b.修改a部分,传递结构的值而不是结构地址。
解:
代码如下:
//a
#include
#include
#define LEN1 5
#define LEN2 20
#define LEN3 10
struct fullname {
char lastname[LEN2];
char middlename[LEN2];
char firstname[LEN2];
};
struct info {
char num[LEN3];
struct fullname name;
};
void show(struct info * ptr);
int main(void)
{
struct info infos[LEN1] = {
{"111111111",{"panda","","zhang"}},
{"111111112",{"pandb","Jsns","zhang"}},
{"111111113",{"pandc","Dok","zhang"}},
{"111111114",{"pandd","Lkjd","zhang"}},
{"111111115",{"pande","Mshd","zhang"}}
};
show(infos);
return 0;
}
void show(struct info * ptr)
{
int i;
for(i = 0;i < LEN1;i++)
{
if(strlen(ptr[i].name.middlename))
printf("%s,%s %c. - %s\n",ptr[i].name.firstname,ptr[i].name.lastname,ptr[i].name.middlename[0],ptr[i].num);
else
printf("%s,%s - %s\n",ptr[i].name.firstname,ptr[i].name.lastname,ptr[i].num);
}
}
//b
#include
#include
#define LEN1 5
#define LEN2 20
#define LEN3 10
struct fullname {
char lastname[LEN2];
char middlename[LEN2];
char firstname[LEN2];
};
struct info {
char num[LEN3];
struct fullname name;
};
void show(struct info inf);
int main(void)
{
struct info infos[LEN1] = {
{"111111111",{"panda","","zhang"}},
{"111111112",{"pandb","Jsns","zhang"}},
{"111111113",{"pandc","Dok","zhang"}},
{"111111114",{"pandd","Lkjd","zhang"}},
{"111111115",{"pande","Mshd","zhang"}}
};
int i;
for(i = 0;i < LEN1;i++)
show(infos[i]);
return 0;
}
void show(struct info inf)
{
int i;
if(strlen(inf.name.middlename))
printf("%s,%s %c. - %s\n",inf.name.firstname,inf.name.lastname,inf.name.middlename[0],inf.num);
else
printf("%s,%s - %s\n",inf.name.firstname,inf.name.lastname,inf.num);
}
———————————————分割线—————————————————
第五题:写一个程序,满足下列要求:
a.外部定义一个name结构模板,它含有2个成员:一个字符串用于存放名字,另一个字符串用于存放姓氏。
b.外部定义一个student结构模板,它含有3个成员:一个name结构,一个存放3个浮点数分数的grade数组,以及一个存放这3个分数的平均分的变量。
c.使main()函数声明一个具有CSIZE(CSIZE=4)个student结构的数组,并随意初始化这些结构的名字部分。使用函数来执行d、e、f以及g部分所描述的任务。
d.请求用户输入学生姓名和分数,以交互地获取每个学生的成绩。将分数放到相应结构的grade数组成员中。您可以自主选择在main()或一个函数中实现这个循环。
e.为每个结构计算平均分,并把这个值赋值给适合的成员。
f.输出每个结构中的信息。
g.输出结构的每个数值成员的班级平均分。
解:假定科目为语文、数学和英语
代码如下:
#include
#define CSIZE 4
#define SIZE 20
struct name {
char firstname[SIZE];
char lastname[SIZE];
};
struct student {
struct name fname;
float grade[3];
float avg;
};
struct student getinfo(struct student s);
struct student avgcompute(struct student s);
void show(struct student s);
void showavg(struct student * ptr);
int main(void)
{
struct student stds[CSIZE] = {
{.fname.firstname = "bao"},
{.fname.firstname = "bei"},
{.fname.firstname = "bu"},
{.fname.firstname = "ku"}
};
int i;
for(i = 0;i < CSIZE;i++)
{
stds[i] = getinfo(stds[i]);
stds[i] = avgcompute(stds[i]);
}
for(i = 0;i < CSIZE;i++)
{
show(stds[i]);
}
showavg(stds);
return 0;
}
struct student getinfo(struct student s)
{
printf("Input %s's lastname:\n",s.fname.firstname);
gets(s.fname.lastname);
printf("Input %s's yu grade:\n",s.fname.firstname);
scanf("%f",&s.grade[0]);
while(getchar() != '\n');
printf("Input %s's shu grade:\n",s.fname.firstname);
scanf("%f",&s.grade[1]);
while(getchar() != '\n');
printf("Input %s's english grade:\n",s.fname.firstname);
scanf("%f",&s.grade[2]);
while(getchar() != '\n');
return s;
}
struct student avgcompute(struct student s)
{
s.avg = (s.grade[0] + s.grade[1] + s.grade[2]) / 3.0;
return s;
}
void show(struct student s)
{
printf("name:%s %s,grade:yu(%.2f) shu(%.2f) en(%.2f) average:%.2f\n",s.fname.firstname,s.fname.lastname,s.grade[0],s.grade[1],s.grade[2],s.avg);
}
void showavg(struct student * ptr)
{
int i;
float to_y = 0.0;
float to_s = 0.0;
float to_e = 0.0;
for(i = 0;i < CSIZE;i++)
{
to_y += ptr[i].grade[0];
to_s += ptr[i].grade[1];
to_e += ptr[i].grade[2];
}
printf("yu:%.2f shu:%.2f en:%.2f all avg:%.2f\n",to_y / 4.0,to_s /4.0,to_e / 4.0,(to_y + to_s + to_e) / 12.0);
}
———————————————分割线—————————————————
第六题:一个文本文件中存放着一个棒球队的信息。每一行的数据都是这样排列的:
4 Jessie Joybat 5 2 1 1
第一项是球员号码,为了方便,范围是0到18.第二项是球员的名,第三项是姓。姓和名都是单个的单词。下一项是官方统计的球员上场次数,紧跟着是击中数、走垒数和跑点数(RBI)。文件可能包括超过一场比赛的数据。因此一个球员可能会有多余一行的数据,而且在不同的行之间有可能有别的球员的数据。写一个程序,把这些数据存储到一个结构数组中。结构中必须含有姓、名、上场次数、击中数、走垒数和跑点数,以及击球平均成功率(稍后计算)。可以使用球员号码作为数组索引。程序应该读到文件末尾,并且应该保存每个球员的累计总和。
这个棒球运动中的统计方法是相关的。例如,一次走垒和触垒中的失误并不会记作上场次数,但是这可能产生一个RBI。可是,该程序所要做的只是处理数据文件,而不必关心数据的实际含义。要实现这些功能,最简单的方法是把结构的内容初始化为零值,将文件的数据读入临时变量中,然后把它们加到相应结构的内容中。程序读完文件后,应该计算每个球员的击球平均成功率,并把它保存到相应的结构成员里。计算击球平均成功率是用球员的累积击中数除以上次累计次数;这是个浮点数计算。然后程序要显示每个球员的累计数据,并且对整个时期显示一行综合统计数据。
解:模拟这个文件是stdin
代码如下:
#include
#include
#define SIZE 20
#define INDEX 19
struct info {
char firstname[SIZE];
char lastname[SIZE];
int times;
int hit;
int zou;
int rbi;
float avg;
};
int main(void)
{
struct info infos[INDEX] = {};
int n,m,i;
puts("Input player number(q to quit):");
while(scanf("%d",&n))
{
while(getchar() != '\n');
if(!strlen(infos[n].firstname))
{
puts("Input player's firstname:");
gets(infos[n].firstname);
puts("Input player's lastname:");
gets(infos[n].lastname);
}
puts("Input times:");
scanf("%d",&m);
while(getchar() != '\n');
infos[n].times += m;
puts("Input hit:");
scanf("%d",&m);
while(getchar() != '\n');
infos[n].hit += m;
puts("Input zou:");
scanf("%d",&m);
while(getchar() != '\n');
infos[n].zou += m;
puts("Input rbi:");
scanf("%d",&m);
while(getchar() != '\n');
infos[n].rbi += m;
puts("Input next player number(q to quit):");
}
for(i = 0;i < INDEX;i++)
infos[i].avg = (float)infos[i].hit / (float)infos[i].times;
for(i = 0;i < INDEX;i++)
if(strlen(infos[i].firstname))
printf("number:%d name: %s %s times:%d hits:%d zou:%d rbi:%d avg:%.2f\n",
i,infos[i].firstname,infos[i].lastname,infos[i].times,infos[i].hit,infos[i].zou,infos[i].rbi,infos[i].avg);
return 0;
}
———————————————分割线—————————————————
第七题:修改程序清单14.14,在从文件中读出每个记录并且显示它时,允许用户选择删除该记录或修改该记录的内容。如果删除记录,把空出来的数组空间留给下一个要读入的记录。要能够改变现有的文件内容,必须使用"r+b"模式,而不是"a+b"模式。要注意文件指针的定位,以便追加的记录不会覆盖已有的记录。最简单的方法是对存储在程序内存中的数据做所有的改变,然后再把最后的信息写入文件中。
解:题意不便理解,不知是删除后添加是使用插入模式还是附加模式,那便补全模式:显示,新增,删除,插入,保存并退出,为了删除结构,引用了memory.h中的memset()。
代码如下:
#include
#include
#include
#include
#define MAXTITL 40
#define MAXAUTL 40
#define MAXBKS 10
struct book {
char title[MAXTITL];
char author[MAXAUTL];
float value;
};
char getchoice(void);
void print(struct book * library,int count);
int add(struct book * library,int count);
int del(struct book * library,int count);
int insert(struct book * library,int count);
void save(struct book * library,int count,FILE * fp);
int main(void)
{
struct book library[MAXBKS];
int count = 0;
int index,filecount;
FILE * pbooks;
int size = sizeof(struct book);
char ch;
if((pbooks = fopen("book.dat","r+b")) == NULL)
{
fputs("Can't open book.dat file,create one\n",stderr);
pbooks = fopen("book.dat","a+b");
}
rewind(pbooks);
while(count < MAXBKS && fread(&library[count],size,1,pbooks) == 1)
{
if(count ==0)
puts("Current contents of book.dat:");
printf("number %d: %s by %s: $%.2f\n",count + 1,library[count].title,library[count].author,library[count].value);
count++;
}
fclose(pbooks);
while((ch = getchoice()) != 'q')
{
switch(ch)
{
case 'p':print(library,count);
break;
case 'a':count = add(library,count);
break;
case 'd':count = del(library,count);
break;
case 'i':count = insert(library,count);
break;
case 's':save(library,count,pbooks);
}
}
puts("Bye.");
return 0;
}
char getchoice(void)
{
int ch;
do
{
puts("You can do");
puts("p)print all books a)add books");
puts("d)delete a book i)insert a book between books");
puts("s)save change and quit q)without save and quit");
scanf("%c",&ch);
while(getchar() != '\n');
}while(!strchr("padisq",ch) && puts("wrong choice,try again"));
return ch;
}
void print(struct book * library,int count)
{
int i;
if(count == 0)
puts("Sorry,no book!");
else
for(i = 0;i < count;i++)
printf("number %d: %s by %s: $%.2f\n",
i + 1,library[i].title,library[
i
].author,library[i].value);
}
int add(struct book * library,int count)
{
int i;
if(count == MAXBKS)
puts("Sorry,only save 10 books!");
else
for(i = count,puts("book title([Enter] at start to quit):");i < MAXBKS,gets(library[i].title) != NULL,library[i].title[0] != '\0';)
{
puts("book author:");
gets(library[i].author);
puts("book value:");
scanf("%f",&library[i].value);
while(getchar() != '\n');
i++;
if(i < MAXBKS)
puts("next book title");
}
return i;
}
int del(struct book * library,int count)
{
int i;
if(count == 0)
puts("Sorry,no book!");
else
{
print(library,count);
puts("which number your will delete(0 to quit):");
while(scanf("%d",&i) && i >0 && i < count)
{
while(getchar() != '\n');
for(i--;i < count - 1;i++)
library[i] = library[i + 1];
memset(&library[count -1],0,sizeof(struct book));
}
}
while(getchar() != '\n');
return count - 1;
}
int insert(struct book * library,int count)
{
int i,j;
if(count == MAXBKS)
{
puts("Sorry,already 10 books!");
return count;
}
else if(count == 0)
puts("No book,you can't choose where to insert but add to 1");
else
{
print(library,count);
puts("which number your will insert(0 to quit):");
}
scanf("%d",&i);
if(i >0 && i <= count)
{
while(getchar() != '\n');
for(j = count;j >= i;j--)
library[j] = library[j - 1];
puts("book title:");
gets(library[i - 1].title);
puts("book author:");
gets(library[i - 1].author);
puts("book value:");
scanf("%f",&library[i - 1].value);
while(getchar() != '\n');
return count + 1;
}
else
{
puts("wrong number!");
return count;
}
}
void save(struct book * lib
rary
,int count,FILE * fp)
{
if((fp = fopen("book.dat","wb")) == NULL)
{
fputs("Can't open book.dat file\n",stderr);
exit(2);
}
if(fwrite(library,count * sizeof(struct book),1,fp))
{
puts("saved");
fclose(fp);
exit(0);
}
else
puts("save failed");
fclose(fp);
}
———————————————分割线—————————————————
第八题:巨人航空公司的机群由作为容量为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)。
e.每次运行程序都把数据保存到一个文件中。当程序再次运行时,首先从文件中载入数据(如果有的话)。
解:抽象为对一个文件进行数据的管理。
代码如下:
#include
#include
#include
#include
#define INDEX 12
#define LEN 20
struct customer {
int index;
_Bool own;
char last[LEN];
char first[LEN];
};
char getchoice(void);
void show_n(struct customer * plane);
void show_l(struct customer * plane);
void show_a(struct customer * plane);
void assign(struct customer * plane);
void delete(struct customer * plane);
int main(void)
{
struct customer plane[INDEX] = {
{.index = 1,.own = false},
{.index = 2,.own = false},
{.index = 3,.own = false},
{.index = 4,.own = false},
{.index = 5,.own = false},
{.index = 6,.own = false},
{.index = 7,.own = false},
{.index = 8,.own = false},
{.index = 9,.own = false},
{.index = 10,.own = false},
{.index = 11,.own = false},
{.index = 12,.own = false}
};
char ch;
FILE * fp;
char file[] = "customer.list";
int size = sizeof(struct customer);
int count = 0;
if((fp = fopen(file,"r+b")) == NULL)
{
fputs("Can't open file,create one\n",stderr);
fp = fopen(file,"a+b");
}
rewind(fp);
while(count < INDEX)
fread(&plane[count++],size,1,fp);
fclose(fp);
while((ch = getchoice()) != 'f')
{
switch(ch)
{
case 'a':show_n(plane);
break;
case 'b':show_l(plane);
break;
case 'c':show_a(plane);
break;
case 'd':assign(plane);
break;
case 'e':delete(plane);
}
}
if((fp = fopen(file,"wb")) == NULL)
{
fputs("Can't open file\n",stderr);
exit(2);
}
if(fwrite(plane,INDEX * size,1,fp))
{
puts("saved");
fclose(fp);
exit(0);
}
else
puts("save failed");
fclose(fp);
puts("Bye.");
return 0;
}
char getchoice(void)
{
char ch;
do
{
puts("To choose a function,enter its letter label:");
puts("a)Show number of empty seats");
puts("b)Show list of empty seats");
puts("c)Show alphabetical list of seats");
puts("d)Assign a customer to a seat assignment");
puts("e)Delete a seat assignment");
puts("f)Quit");
scanf("%c",&ch);
while(getchar() != '\n');
}while(!strchr("abcdef",ch) && puts("wrong choice,try again"));
return ch;
}
void show_n(struct customer * plane)
{
int n,m;
for(n = 0,m = 0;n < INDEX;n++)
if(!plane[n].own)
m++;
printf("%d empty seats\n",m);
}
void show_l(struct customer * plane)
{
int n;
puts("empty seats index:");
for(n = 0;n < INDEX;n++)
if(!plane[n].own)
printf(" %d",plane[n].index);
puts("");
}
void show_a(struct customer * plane)
{
char * ptr[INDEX];
int n,m;
char * temp;
for(n = 0;n < INDEX;n++)
ptr[n] = plane[n].first;
for(n = 0;n < INDEX - 1;n++)
for(m = n + 1;m < INDEX; m++)
if(strcmp(ptr[n],ptr[m]) > 0)
{
temp = ptr[n];
ptr[n] = ptr[m];
ptr[m] = temp;
}
for(n = 0;n < INDEX;n++)
for(m = 0;m < INDEX;m++)
if(strlen(ptr[n]) > 0 && strcmp(ptr[n],plane[m].first) == 0)
printf("%s %s own seat %d\n",plane[m].first,plane[m].last,plane[m].index);
}
void assign(struct customer * plane)
{
int n = 1;
show_l(plane);
puts("which index do you want to assign(0 to back):");
while(scanf("%d",&n) && n > 0 && n <= INDEX)
{
while(getchar() != '\n');
if(!plane[--n].own)
{
puts("Input lastname:");
gets(plane[n].last);
puts("Input firstname:");
gets(plane[n].first);
plane[n].own = true;
}
else
puts("it is owned,try again");
puts("which index do you want to assign(0 to back):");
}
while(getchar() != '\n');
}
void delete(struct customer * plane)
{
int n;
puts("owned seats index:");
for(n = 0;n < INDEX;n++)
if(plane[n].own)
printf(" %d:%s %s\n",plane[n].index,plane[n].first,plane[n].last);
puts("which index do you want to delete(0 to back):");
while(scanf("%d",&n) && n > 0 && n <= INDEX)
{
while(getchar() != '\n');
if(plane[--n].own)
{
plane[n].own = false;
strcpy(plane[n].last,"");
strcpy(plane[n].first,"");
}
else
puts("it is empty,try again");
puts("which index do you want to delete(0 to back):");
}
while(getchar() != '\n');
}
———————————————分割线—————————————————
第九题:巨人航空公司(见第八题)需要另一架飞机(同样容量),并使它每天服务4个航班(航班102、311、444和519)。把程序扩展为能够处理4个航班。有一个顶层菜单可供选择航班和退出。选择了一个特定的航班,就会调出和第八题相似的菜单,但要加上一个新项:确认一个座位分配;并用一个退回顶层菜单的选项代替退出选项。每个显示要指明现在正在处理哪个航班。座位分配显示必须要指明确认状态。
解:将航班号加入到乘客的结构中,并且用4个文件来管理4个航班的信息
代码如下:
#include
#include
#include
#include
#define INDEX 12
#define LEN 20
struct customer {
int flt_no;
int index;
_Bool own;
_Bool confirm;
char last[LEN];
char first[LEN];
};
int getflt(void);
char getchoice(void);
void show_n(struct customer * plane);
void show_l(struct customer * plane);
void show_a(struct customer * plane);
void assign(struct customer * plane);
void confirm(struct customer * plane);
void delete(struct customer * plane);
int main(void)
{
struct customer planetmp[INDEX] = {
{.index = 1,.own = false,.confirm = false},
{.index = 2,.own = false,.confirm = false},
{.index = 3,.own = false,.confirm = false},
{.index = 4,.own = false,.confirm = false},
{.index = 5,.own = false,.confirm = false},
{.index = 6,.own = false,.confirm = false},
{.index = 7,.own = false,.confirm = false},
{.index = 8,.own = false,.confirm = false},
{.index = 9,.own = false,.confirm = false},
{.index = 10,.own = false,.confirm = false},
{.index = 11,.own = false,.confirm = false},
{.index = 12,.own = false,.confirm = false}
};
struct customer plane[INDEX];
int flt;
char ch;
FILE * fp;
char file[LEN];
int size = sizeof(struct customer);
int count = 0;
while((flt = getflt()) != 0)
{
for(count = 0;count < INDEX;count++)
plane[count] = planetmp[count];
switch(flt)
{
case 102:for(count = 0;count < INDEX;count++)
plane[count].flt_no = 102;
strcpy(file,"FLT_NO102") ;
break;
case 311:
for(count = 0;count < INDEX;count++)
plane[count].flt_no = 311;
strcpy(file,"FLT_NO311") ;
break;
case 444:
for(count = 0;count < INDEX;count++)
plane[count].flt_no = 444;
strcpy(file,"FLT_NO44") ;
break;
case 519:
for(count = 0;count < INDEX;count++)
plane[count].flt_no = 519;
strcpy(file,"FLT_NO519") ;
}
if((fp = fopen(file,"r+b")) == NULL)
{
fputs("Can't open file,create one\n",stderr);
fp = fopen(file,"a+b");
}
rewind(fp);
count = 0;
while(count < INDEX)
fread(&plane[count++],size,1,fp);
fclose(fp);
while((ch = getchoice()) != 'g')
{
switch(ch)
{
case 'a':show_n(plane);
break;
case 'b':show_l(plane);
break;
case 'c':show_a(plane);
break;
case 'd':assign(plane);
break;
case 'e':confirm(plane);
break;
case 'f':delete(plane);
}
}
if((fp = fopen(file,"wb")) == NULL)
{
fputs("Can't open file\n",stderr);
exit(2);
}
if(fwrite(plane,INDEX * size,1,fp))
puts("saved");
else
puts("save failed");
fclose(fp);
}
puts("Bye.");
return 0;
}
int getflt(void)
{
int ch;
do
{
puts("To choose flight no(0 to quit) :");
puts("102 311 444 519");
scanf("%d",&ch);
while(getchar() != '\n');
}while(ch != 102 && ch != 311 && ch != 444 && ch != 519 && ch != 0 && puts("wrong choice,try again"));
return ch;
}
char getchoice(void)
{
char ch;
do
{
puts("To choose a function,enter its letter label:");
puts("a)Show number of empty seats");
puts("b)Show list of empty seats");
puts("c)Show alphabetical list of seats");
puts("d)Assign a customer to a seat assignment");
puts("e)Confirm the a seat
assignment");
puts("f)Delete a seat assignment");
puts("g)Back");
scanf("%c",&ch);
while(getchar() != '\n');
}while(!strchr("abcdefg",ch) && puts("wrong choice,try again"));
return ch;
}
void show_n(struct customer * plane)
{
int n,m;
for(n = 0,m = 0;n < INDEX;n++)
if(!plane[n].own)
m++;
printf("%d empty seats\n",m);
}
void show_l(struct customer * plane)
{
int n;
puts("empty seats index:");
for(n = 0;n < INDEX;n++)
if(!plane[n].own)
printf(" %d",plane[n].index);
puts("");
}
void show_a(struct customer * plane)
{
char * ptr[INDEX];
int n,m;
char * temp;
for(n = 0;n < INDEX;n++)
ptr[n] = plane[n].first;
for(n = 0;n < INDEX - 1;n++)
for(m = n + 1;m < INDEX; m++)
if(strcmp(ptr[n],ptr[m]) > 0)
{
temp = ptr[n];
ptr[n] = ptr[m];
ptr[m] = temp;
}
for(n = 0;n < INDEX;n++)
for(m = 0;m < INDEX;m++)
if(strlen(ptr[n]) > 0 && strcmp(ptr[n],plane[m].first) == 0)
printf("FLT_NO:%d index:%d name:%s %s\n",plane[m].flt_no,plane[m].index,plane[m].first,plane[m].last);
}
void assign(struct customer * plane)
{
int n = 1;
show_l(plane);
puts("which index do you want to assign(0 to back):");
while(scanf("%d",&n) && n > 0 && n <= INDEX)
{
while(getchar() != '\n');
if(!plane[--n].own)
{
puts("Input lastname:");
gets(plane[n].last);
puts("Input firstname:");
gets(plane[n].first);
plane[n].own = true;
}
else
puts("it is owned,try again");
puts("which index do you want to assign(0 to back):");
}
while(getchar() != '\n');
}
void confirm(struct customer * plane)
{
int n;
puts("unconfirmed seats index:");
for(n = 0;n < INDEX;n++)
if(plane[n].own && !plane[n].confirm)
printf("FLT_NO:%d index:%d name:%s %s\n",plane[n].flt_no,plane[n].index,plane[n].first,plane[n].last);
puts("which index do you want to confirm(0 to back):");
while(scanf("%d",&n) && n > 0 && n <= INDEX)
{
while(getchar() != '\n');
if(plane[--n].own && !plane[n].confirm)
{
plane[n].confirm = true;
}
else
puts("it is not owned or it had confirmed,try again");
puts("which index do you want to confirm(0 to back):");
}
while(getchar() != '\n');
}
void delete(struct customer * plane)
{
int n;
puts("owned seats index:");
for(n = 0;n < INDEX;n++)
if(plane[n].own)
printf("FLT_NO:%d index:%d name:%s %s\n",plane[n].flt_no,plane[n].index,plane[n].first,plane[n].last);
puts("which index do you want to delete(0 to back):");
while(scanf("%d",&n) && n > 0 && n <= INDEX)
{
while(getchar() != '\n');
if(plane[--n].own)
{
plane[n].own = false;
strcpy(plane[n].last,"");
strcpy(plane[n].first,"");
}
else
puts("it is empty,try again");
puts("which index do you want to delete(0 to back):");
}
while(getchar() != '\n');
}
———————————————分割线—————————————————
第十题:编写一个程序,用指向函数的指针数组执行菜单。例如,在菜单中选择a会激活由数组第一个元素指向的函数。
解:
代码如下:
#include
void ta(void);
void tb(void);
void print(void (* fp)(void));
int main(void)
{
void (* fp[2])(void);
fp[0] = ta;
fp[1] = tb;
char ch;
do
{
puts("you have a choose like:");
puts("a)use function a");
puts("b)use function b");
scanf("%c",&ch);
while(getchar() != '\n');
}while(ch != 'a' && ch != 'b' && puts("wrong choice,try again"));
if(ch == 'a')
print(fp[0]);
else
print(fp[1]);
return 0;
}
void ta(void)
{
printf("I am temp function a\n");
}
void tb(void)
{
printf("I am temp function b\n");
}
void print(void (* fp)(void))
{
(* fp)();
}
———————————————分割线—————————————————
第十一题:编写一个transform()函数,它接收4个参数:包含double类型数据的源数组名,double类型的目标数组名,表示数组元素个数的int变量以及一个函数名(或者,等价的指向函数的指针)。transform()函数把指定的函数作用于源数组的每个元素,并将返回值放到目标数组中。例如:
transform(source,target,100,sin);
这个函数调用把sin(source[0])赋给target[0],等等,共有100个元素。在一个程序中测试该函数,调用4次transform(),分别使用math.h函数库中的两个函数以及自己设计的两个合适的函数作为参数。
解:
代码如下:
#include
#include
double addone(double n);
double reduceone(double n);
void transform(double * source,double * target,int n,double (* fp)(double m));
int main(void)
{
double source[10] = {0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0};
double target[10];
int i;
double (* fp)(double m);
puts("source:");
for(i = 0;i < 10;i++)
printf(" %.2f",source[i]);
puts("");
puts("function sin:");
transform(source,target,10,sin);
puts("function cos:");
transform(source,target,10,cos);
puts("function addone:");
transform(source,target,10,addone);
puts("function reduceone:");
transform(source,target,10,reduceone);
return 0;
}
double addone(double n)
{
return n + 1.0;
}
double reduceone(double n)
{
return n - 1.0;
}
void transform(double * source,double * target,int n,double (* fp)(double m))
{
int i;
for(i = 0;i < 10;i++)
{
target[i] = fp(source[i]);
printf(" %.2f",target[i]);
}
puts("");
}
运行说明:如果编译时提示sin和cos未定义,错误原因主要是没有定义“sin”函数,或者说没有找到“sin”函数的实现,虽然我们在函数开头声明了数学函数库,但还是没有找到sin的实现,这时我们就需要指定sin函数的具体路径了。
[ root@c cpp]# gcc 14_11.c
/tmp/ccJhYNWJ.o: In function `main':
14_11.c:(.text+0xf7): undefined reference to `sin'
14_11.c:(.text+0x11e): undefined reference to `cos'
collect2: error: ld returned 1 exit status
[ root@c cpp]# gcc 14_11.c -lm
[ root@c cpp]# ./a.out
source:
0.00 1.00 2.00 3.00 4.00 5.00 6.00 7.00 8.00 9.00
function sin:
0.00 0.84 0.91 0.14 -0.76 -0.96 -0.28 0.66 0.99 0.41
function cos:
1.00 0.54 -0.42 -0.99 -0.65 0.28 0.96 0.75 -0.15 -0.91
function addone:
1.00 2.00 3.00 4.00 5.00 6.00 7.00 8.00 9.00 10.00
function reduceone:
-1.00 0.00 1.00 2.00 3.00 4.00 5.00 6.00 7.00 8.00