您的位置:首页 > 编程语言

C Primer Plus (第五版) 第十四章 结构和其它数据形式 编程练习

2015-06-10 17:36 471 查看
重做复习题3.但用月份名的拼写代替月份号(别忘了可以使用strcmp())。

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

struct month {
char name[10];
char abbrev[4];
int days;
int number;
};
struct month months[12] = {
{ "January", "JAN", 31, 1 },
{ "February", "FEB", 29, 2 },
{ "March", "MAR", 31, 3 },
{ "April", "APR", 30, 4 },
{ "May", "MAY", 31, 5 },
{ "June", "JUN", 30, 6 },
{ "July", "JUL", 31, 7 },
{ "August", "AUG", 31, 8 },
{ "September", "SEP", 30, 9 },
{ "October", "OCT", 31, 10 },
{ "November", "NOV", 30, 11 },
{ "December", "DEC", 31, 12 }
};

int fun(char * mon);

int main(void)
{
char mon[10];
int days;

printf("请输入月份,要求首字母大写:");
while (gets(mon) && mon[0] != '\0')
{
days = fun(mon);
if (days)
printf("一年中(非闰年)到该月结束共有%d天\n", fun(mon));
else
printf("程序不能识别月份。\n");
printf("请再次输入月份,要求首字母大写,在开始处输入回车结束:");
}

printf("结束。\n");
return 0;
}

int fun(char * mon)
{
int i, num = 0;

for (i = 0; i < 12; i++)
{
num += months[i].days;
if (strcmp(mon, months[i].name) == 0)
break;
}
if (i == 12)
return 0;

return num;
}


2.请求用户键入日、月、年。月份可以是月分号、月份名或月份缩写。然后程序返回一年中给定日子(包括这一天)的总天数
#include<stdio.h>

int days(int day, int mon, int year);
int leapyear(int year);
int input(int *, int *);	//实现月份可以是月分号、月份名或月份缩写
struct month{
char name[10];
char abbrev[4];
int days;
int monumb;
};

struct month months[12] = {
{ "january", "jan", 31, 1 },
{ "february", "feb", 28, 2 },
{ "march", "mar", 31, 3 },
{ "april", "apr", 30, 4 },
{ "may", "may", 31, 5 },
{ "june", "jun", 30, 6 },
{ "july", "jul", 31, 7 },
{ "august", "aug", 31, 8 },
{ "september", "sep", 30, 9 },
{ "october", "oct", 31, 10 },
{ "november", "nov", 30, 11 },
{ "december", "dec", 31, 12 }
};
int main(void)
{
int year, day, mon;

printf("请输入年份:");
while (scanf("%d", &year) == 1)
{
if (input(&mon, &day))
printf("%d-%d-%d 是这一年中的第 %d 天\n",
year, mon, day, days(year, mon, day));
else
printf("输入出错。\n");
while (getchar() != '\n');
printf("请再次输入年份,输入q结束程序:");
}
printf("结束。\n");

return 0;
}
int days(int year, int mon, int day)
{
int days = 0;

leapyear(year) ? months[1].days = 29 : (months[1].days = 28);
for (int i = 0; i < mon - 1; i++)
days += months[i].days;
return (days + day);
}
int leapyear(int year)
{
if (year % 400 == 0)
{
return 1;
}
else
{
if (year % 100 != 0 && year % 4 == 0)
return 1;
}
return 0;
}
int input(int *pm, int *pd)
{
char mname[10];
int number;

printf("请输入月份:");
if (scanf("%d", &number) == 1)
*pm = number;
else
{
gets(mname);
int i;
for (i = 0; i < 12; i++)
if (strcmp(mname, months[i].name) == 0 ||
strcmp(mname, months[i].abbrev) == 0)
{
*pm = months[i].monumb;
break;
}
if (12 == i)
return 0;
}
printf("请输入日期:");
if (scanf("%d", pd)!=1)
return 0;

return 1;
}


3.修改程序清单l4.2中的书目列表程序,使它首先按照输入的顺序输出图书的描述,
然后按照标题的字母升序输出图书的描述,最后按照value值的升序输出图书的描述。
# include <stdio.h>
# define MAXTITL 40
# define MAXAUTL 40
# define MAXBKS 100
struct book
{
char title[MAXTITL];
char author[MAXAUTL];
float value;
};

void show(struct book * a[], int n);
int main(void)
{
struct book library[100];
struct book * plib[100];
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);
plib[count] = &library[count];
count++;
while (getchar() != '\n')
continue;
if (count < MAXBKS)
printf("Enter the next title.\n");
}
if (count > 0)
{
printf("Hera 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);
printf("\n按照标题定母升序显示:\n");
show(plib, count);
}
else
printf("No books? Too bad.\n");
return 0;
}

#include <string.h>
void show(struct book * a[], int n)
{
struct book * temp;

int i, j;
for (i = 0; i < n - 1; i++)
{
for (j = i + 1; j < n; j++)
if (strcmp(a[i]->title, a[j]->title) >0)
{
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
for (i = 0; i < n; i++)
printf("%s by %s: $%.2f\n",
a[i]->title, a[i]->author, a[i]->value);
}


4.编写一个程序。按照下列要求,创建一个含有两个成员的结构模板:
a.第一个成员是社会保障号;第二个成员是一个含三个成员的结构。它的第一个成员是名,第二个成员是名和姓中间的名字,最后一个成员是姓。创建并初始化一个含有5个此类结构的数组。程序以下列形式输出数据:
Dribble.Flossie M. - 302039823
名和姓中间的名字只输出了它的第一个字母,后面加了一个句点。如果姓名中间的名字为空,那么它的第一个字母和句点都不会输出(当然喽)。写一个函数来实现输出,把结构数组传递给这个函数。
b.修改a部分,传递结构而不是结构地址。
/*
4.编写一个程序。按照下列要求,创建一个含有两个成员的结构模板:
a.第一个成员是社会保障号;第二个成员是一个含三个成员的结构。它的第一个成员是名,第二个成员是名和姓中间的名字,最后一个成员是姓。创建并初始化一个含有5个此类结构的数组。程序以下列形式输出数据:
Dribble.Flossie M. - 302039823
名和姓中间的名字只输出了它的第一个字母,后面加了一个句点。如果姓名中间的名字为空,那么它的第一个字母和句点都不会输出(当然喽)。写一个函数来实现输出,把结构数组传递给这个函数。
b.修改a部分,传递结构而不是结构地址。
*/

#include <stdio.h>
struct fullname{
char firstname[20];
char middlename[20];
char lastname[20];
}name;
struct info{
int number;
struct fullname name;
};
void show_a(struct info st);
void show_b(struct info * pst, int n);

int main(void)
{
struct info nssf[5] = {
{ 302039823, { "Dribble", "Mackede", "Flossie" } },
{ 345345345, { "gadenfs", "Kasdfas", "Pszajkh" } },
{ 302039823, { "Kazsdfj", "Aasdfaf", "Mjasdfh" } },
{ 302039823, { "Qaadsef", "", "Yjsjdsh" } },
{ 302039823, { "Bsdsdfs", "Fsjdsdd", "Rshdsdf" } }
};
printf("a.传递结构显示:\n");
for (int i = 0; i < 5; i++)
show_a(nssf[i]);
printf("\nb.传递结构指针显示:\n");
show_b(nssf, 5);

return 0;
}
void show_a(struct info st)
{
if (st.name.middlename[0] != '\0')
printf("%s.%s %c. - %d\n", st.name.firstname, st.name.lastname,
st.name.middlename[0], st.number);
else
printf("%s.%s - %d\n", st.name.firstname,
st.name.lastname, st.number);
}

void show_b(struct info * pst, int n)
{
for (int i = 0; i < n; i++)
{

if (pst[i].name.middlename[0] != '\0')
printf("%s.%s %c. - %d\n", pst[i].name.firstname, pst[i].name.lastname,
pst[i].name.middlename[0], pst[i].number);
else
printf("%s.%s - %d\n", pst[i].name.firstname,
pst[i].name.lastname, pst[i].number);
}
}


5.写一个程序,满足下列要求:
外部定义一个name结构模板,它含有2个成员:一个字符串用于存放名字,另—个字符串用于存放姓氏。

外部定义一个student结构模板,它含有3个成员:一个 name结构,一个存放3个浮点数分数的 grade数组,以及一个存放这3个分数的平均分的变量。

使main()函数声明一个具自CSIZE (CSIZE=4)个student结构的数组,并随意初始化这些结构的名字部分。使用函数来执行d、e、f以及g部分所描述的任务。

请求用户输入学生姓名和分数,以交互地获取每个学生的成绩。将分数放到相应结构的grade数组成员中。您可以自主选择在main()或一个函数中实现这个循环。

为每个结构计算平均分,并把这个值赋给适合的成员。

输出每个结构中的信息。

输出结构的每个数值成员的班级平均分。

#include <stdio.h>
#define NAMELEN 20
#define CSIZE 4
#define COURSE 3
void input_d(struct student *, int);
void average_e(struct student *, int);
void show_f(const struct student *, int);
void show_g(const struct strudent *, int);

struct name {
char fristname[NAMELEN];
char lastname[NAMELEN];
};
struct student{
struct name name;
double grade[COURSE];
double average;
};
int main(void)
{
struct student result[CSIZE] =
{
{ {  "大大", "习"  } },
{ { "涛哥", "胡" } },
{ { "二货", "江" } },
{ {  "伟人", "毛" } }
};

input_d(result, CSIZE);
average_e(result, CSIZE);
show_f(result, CSIZE);
show_g(result, CSIZE);

return 0;
}

void input_d(struct student * pst, int n)
{
int i, j;

for (i = 0; i < n; i++)
{
printf("请输入 %s%s 的三科成绩:",
pst[i].name.lastname, pst[i].name.fristname);
scanf("%lf%lf%lf",
&pst[i].grade[0], &pst[i].grade[1], &pst[i].grade[2]);
}
}
void average_e(struct student * pst, int n)
{
int i, j;
double sum;
for (i = 0; i < n; i++)
{
for (j = 0, sum = 0.0; j < COURSE; j++)
sum += pst[i].grade[j];
pst[i].average = sum / 3.0;
}
}
void show_f(const struct student * pst, int n)
{
int i, j;
puts("班级整体情况:");
for (i = 0; i < n; i++)
{
printf("%s%s \t\t", pst[i].name.lastname, pst[i].name.fristname);
for (j = 0; j < COURSE; j++)
printf("%5.2lf \t", pst[i].grade[j]);
printf("%5.2lf\n", pst[i].average);
}
}
void show_g(const struct student * pst, int n)
{
int i, j;
double sum;
printf("每科平均分:\t");
for (i = 0; i < COURSE; i++)
{
for (j = 0, sum = 0; j < n; j++)
sum += pst[j].grade[i];
printf("%5.2lf\t", sum / n);
}
printf("\n");
}


6.一个文本文件中存放着一个棒球队的信息。每一行的数据都是这样排列的:
4 Jessie Joybat 5 2 1 1
第一项是球员号码,为了方便,范围是0到18。第二项是球员的名,第三项是姓。姓和名都是单个的单词。下一项是官方统计的球员上场次数,紧跟着是击中数、走垒数和跑点数( RBI)。文件可能包括超过一场比赛的数据,因此同一个球员可能会有多于一行的数据,而且在不同的行之间有可能有别的球员的数据。
一个程序,把这些数据存储到一个结构数组中。结构中必须含有姓、名、上场次数、击中数、走垒数和跑点数,以及击球平均成功率(稍后计算)。可以使用球员号码作为数组索引。程序应该读到文件末尾,并且应该保存每个球员的累计总和。这个棒球运动中的统计方法是相关的。例如,一次走垒和触垒中的失误并不会记作上场次数,但是这可能产生一个RBI。可是,该程序所要做的只是处理数据文件,而不必关心数据的实际含义。要实现这些功能,最简单的方法是把结构的内容初始化为零值,将文件数据读入临时变量中,然后把它们加到相应结构的内容中。程序读完文件后,应该计算每个球员的击球平均成功率,并把它保存到相应的结构成员里。计算击球平均成功率是用球员的累计击中数除以上场累计次数;这是个浮点数计算。然后程序要显示每个球员的累计数据,并且对整个时期显示一行综合统计数据。
球员号码 名姓上场次数 击中数跑垒数跑点数
4JessieJoybat5211
/*
文档内容:
0 伯光 田 5 2 1 1
1 伯通 周 4 2 1 1
2 盈盈 任 3 1 1 1
3 吹雪 西门 6 2 1 1
4 狐冲 令 5 3 1 1
5 我行 任 2 0 1 1
6 求败 独孤 0 0 0 0
7 小凤 陆 5 3 1 1
8 彩蝶 蓝 5 2 1 2
9 靖 郭 5 2 2 1
17 彩臣 宁 3 2 1 1
10 芷若 周 3 0 1 1
11 无忌 张 5 2 0 1
6 求败 独孤 3 3 1 1
12 敏 赵 7 4 1 1
13 峰 乔 8 6 1 1
14 誉 段 10 2 5 7
15 童佬 天山 3 1 1 1
16 老妖 黑山 5 2 0 1
17 彩臣 宁 6 2 1 1
18 特曼 奥 1 1 1 1
6 求败 独孤 2 2 0 0
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NAMELEN 15
#define LEN 19

struct player {
char first_name[NAMELEN];
char last_name[NAMELEN];
int field;
int hit;
int base;
int points;
float average;
};
void show_player(struct player *, int);
void fun(struct player *, int);
int main(void)
{
struct player player_info[LEN] = {
{ { '\0' }, { '\0' }, 0, 0, 0, 0, 0.0 },
{ { '\0' }, { '\0' }, 0, 0, 0, 0, 0.0 },
{ { '\0' }, { '\0' }, 0, 0, 0, 0, 0.0 },
{ { '\0' }, { '\0' }, 0, 0, 0, 0, 0.0 },
{ { '\0' }, { '\0' }, 0, 0, 0, 0, 0.0 },
{ { '\0' }, { '\0' }, 0, 0, 0, 0, 0.0 },
{ { '\0' }, { '\0' }, 0, 0, 0, 0, 0.0 },
{ { '\0' }, { '\0' }, 0, 0, 0, 0, 0.0 },
{ { '\0' }, { '\0' }, 0, 0, 0, 0, 0.0 },
{ { '\0' }, { '\0' }, 0, 0, 0, 0, 0.0 },
{ { '\0' }, { '\0' }, 0, 0, 0, 0, 0.0 },
{ { '\0' }, { '\0' }, 0, 0, 0, 0, 0.0 },
{ { '\0' }, { '\0' }, 0, 0, 0, 0, 0.0 },
{ { '\0' }, { '\0' }, 0, 0, 0, 0, 0.0 },
{ { '\0' }, { '\0' }, 0, 0, 0, 0, 0.0 },
{ { '\0' }, { '\0' }, 0, 0, 0, 0, 0.0 },
{ { '\0' }, { '\0' }, 0, 0, 0, 0, 0.0 },
{ { '\0' }, { '\0' }, 0, 0, 0, 0, 0.0 },
{ { '\0' }, { '\0' }, 0, 0, 0, 0, 0.0 },
};
struct player temp;
char file_name[80];
FILE * fp;

printf("请输入你要打开的文件:");
gets(file_name);
if ((fp = fopen(file_name, "r")) == NULL)
{
fprintf(stderr, "%s打开失败\n", file_name);
exit(EXIT_FAILURE);
}
int i;
while (fscanf(fp, "%d%s%s%d%d%d%d", &i,&temp.first_name,&temp.last_name,
&temp.field,&temp.hit,&temp.base,&temp.points) == 7)
{	//将文件内容保存到结构成员中
if (strcmp(player_info[i].first_name, temp.first_name) != 0)
strcpy(player_info[i].first_name, temp.first_name);
if (strcmp(player_info[i].last_name, temp.last_name) != 0)
strcpy(player_info[i].last_name, temp.last_name);
player_info[i].field += temp.field;
player_info[i].hit += temp.hit;
player_info[i].base += temp.base;
player_info[i].points += temp.points;
}
for (i = 0; i < LEN; i++)
{	//计算击球平均成功率
player_info[i].average = (float)player_info[i].hit / (float)player_info[i].field;
}
//显示每个球员的累计数据
show_player(player_info, LEN);
//整个时期显示一行综合统计数据,不理解什么意思,就把每个球员的各项数据相加吧
fun(player_info, LEN);
return 0;
}

void show_player(struct player * pst, int n)
{
int i;
for (i = 0; i < n; i++)
{
printf("%-3s%-8s \t", pst[i].last_name, pst[i].first_name);
printf("%3d %3d %3d %3d %5.1f\n", pst[i].field, pst[i].hit,
pst[i].base, pst[i].points, pst[i].average);
}
}
void fun(struct player * pst, int n)
{
int i;
struct player temp = {
{ '\0' }, { '\0' }, 0, 0, 0, 0, 0.0
};
for (i = 0; i < n; i++)
{
temp.field += pst[i].field;
temp.hit += pst[i].hit;
temp.base += pst[i].base;
temp.points += pst[i].points;
}
temp.average = (float)temp.hit / (float)temp.field;
printf("综合统计:\t%3d %3d %3d %3d %5.1f\n", temp.field, temp.hit,
temp.base, temp.points, temp.average);
}


7.修改程序清单14.14,在从文件中读出每个记录并且显示它时允许用户选择删除或修改该记录的内容。如果删除把空出来的数组空间留给下一个要读入的记录。要能够改变现在的文件内容,必须使用“r+b”模式。要注意文件指针的定位,以便追加的记录不会覆盖已有记录。最简单的方法是对存储在程序内存中的数据做所有改变,然后现把最后的信息集写入文件中。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXTITL 40
#define MAXAUTL 40
#define MAXBKS 10

int menu(void);
int eidt_menu(void);
int get_ch(char *);
void eidt(struct book *);
//声明一个结构体包含三个成员
struct book {
char title[MAXTITL];
char author[MAXAUTL];
float value;
};

int main(void)
{
struct book library[MAXBKS];
int count = 0;
int index;
FILE * pbooks;
int size = sizeof (struct book);

if ((pbooks = fopen("f:\\test\\book.txt", "r+b")) == NULL)
{	//打开文件
fputs("Can't open book.dat file\n", stderr);
exit(1);
}

rewind(pbooks);
int i = 1;	//删除第一条时count会多次为0,i用来确保只输出一次"Current contents of book.dat"
while (count < MAXBKS && fread(&library[count], size, 1, pbooks) == 1)
{

if (count == 0 && i)
{
puts("Current contents of book.dat");
i = 0;
}
printf("%s by %s: $%.2f\n", library[count].title, library[count].author, library[count].value);
switch (menu())
{
case 'e': eidt(&library[count]);
break;
case 'd':
continue;
default:puts("Error!");
}
count++;
}
if (count == MAXBKS)
{
fputs("The book.dat file is full.", stderr);
exit(2);
}
//count < MAXBKS时可添加新内容
puts("Please add new book titles.");
puts("Press [enter] at the start of a line to stop.");
while (count < MAXBKS && gets(library[count].title) != NULL && library[count].title[0] != '\0')
{	//增加新内容
puts("Now enter the author. ");
gets(library[count].author);
puts("Now enter the value.");
scanf("%f", &library[count++].value);
while (getchar() != '\n')
continue;
if (count < MAXBKS)
puts("Enter the next title.");
}

if (count > 0)
{	//输出结构数组内容
puts("Here is the list of your books: ");
for (index = 0; index < count; index++)
printf("%s by %s: $%.2f\n", library[index].title,
library[index].author, library[index].value);
//将整个结构数组写入文件
rewind(pbooks);
fwrite(library, size, count, pbooks);
}
else
puts("No books? Too bad.\n");
puts("Bye.\n");
fclose(pbooks);

return 0;
}

int menu(void)
{	//选择操作菜单,并返回用户输入的字符
puts("请选择对当前显示内容的操作:");
puts("e)编辑\td)删除\tq)不进行操作");

return get_ch("edq");
}

int get_ch(const char * str)
{	//确认用户输入的字符合法
int ch;
while (ch = getchar())
{
while (getchar() != '\n')
;
if (strchr(str, ch))
break;
else
printf("请输入正确的选项 %s:", str);
}

return ch;
}

int eidt_menu(void)
{	//编辑菜单选项
puts("请选择要修改的内容:");
puts("t)书名\t a)作者\t v)价格");
puts("s)退出并保存修改");
puts("q)退出取消修改");
return  get_ch("tavsq");
}

void eidt(struct book * pst)
{	//进行编辑
char ch;
struct book copy = *pst;

while (ch = eidt_menu(), ch != 's' && ch != 'q')
{
switch (ch)
{
case 't': printf("请输入新的书名:");
gets(pst->title);
break;
case 'a': printf("请输入新的作者:");
gets(pst->author);
break;
case 'v': printf("请输入新的价格:");
scanf("%f", &(pst->value));
while (getchar() != '\n')
;
break;
default:puts("Error!");
}
}
if (ch == 'q')
*pst = copy;
}


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)。
e.每次运行程序都把数据到一个文件中。当程序再次运行时,首先从文件中载入数据(如果有的话)。
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#define NUM 12
#define NAMELEN 18
struct names{
char first_name[NAMELEN];
char last_name[NAMELEN];
};
typedef struct air_seat_info {
int number;
bool ide;
struct names name;
} asi;

void menu(void);
int empty_count(asi * pst, int n);
void empty_num(asi * pst, int n);
void alphabetical(asi * pst[], int n);
void d(asi * pst, int n);
void e(asi * pst, int n);
int get_ch(char * str);

int main(void)
{
asi air[NUM] = {
{ 1, false, { { '\0' }, { '\0' } } },
{ 2, false, { { '\0' }, { '\0' } } },
{ 3, false, { { '\0' }, { '\0' } } },
{ 4, false, { { '\0' }, { '\0' } } },
{ 5, false, { { '\0' }, { '\0' } } },
{ 6, false, { { '\0' }, { '\0' } } },
{ 7, false, { { '\0' }, { '\0' } } },
{ 8, false, { { '\0' }, { '\0' } } },
{ 9, false, { { '\0' }, { '\0' } } },
{ 10, false, { { '\0' }, { '\0' } } },
{ 11, false, { { '\0' }, { '\0' } } },
{ 12, false, { { '\0' }, { '\0' } } },
};
asi * pair[NUM];
int i;
char ch;
FILE * pf;
size_t size = sizeof(air);
if ((pf = fopen("f:\\test\\air.txt", "r+b")) == NULL)
{
if ((pf = fopen("f:\\test\\air.txt", "w+b")) == NULL)
{
fprintf(stderr, "文件打开失败\n");
exit(EXIT_FAILURE);
}
}
else
{
rewind(pf);
fread(air, size, 1, pf);
}

for (i = 0; i < NUM; i++)
pair[i] = &air[i];
menu();
while ((ch = get_ch("abcdef")) != 'f')
{
switch (ch)
{
case 'a':printf("empty seats: %d\n", empty_count(air, NUM));
break;
case 'b':empty_num(air, NUM);
break;
case 'c':alphabetical(pair, NUM);
break;
case 'd':d(air, NUM);
break;
case 'e':e(air, NUM);
break;
default:printf("\nError!\n");
}
putchar('\n');
menu();
}
rewind(pf);
fwrite(air, size, 1, pf);
fclose(pf);

return 0;
}

void menu(void)
{
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");
}
int get_ch(char * str)
{
char ch;

while (ch = getchar())
{
while (getchar() != '\n')
;
if (strchr(str, ch) == NULL)
printf("请输入正确的选择,例如%s :", str);
else
break;
}
return ch;
}
int empty_count(asi * pst, int n)
{
int i, count = 0;

for (i = 0; i < n; i++)
if (!pst[i].ide)
count++;
return count;
}
void empty_num(asi * pst, int n)
{
int i = 0;

if (empty_count == 0)
printf("没有空的座位。\n");
else
{
printf("当前空座位号码:\n");
for (i = 0; i < n; i++)
if (!pst[i].ide)
printf("%3d", pst[i].number);
printf("\n");
}
}
void alphabetical(asi * pst[], int n)
{
asi * temp;
int i, j;
if (empty_count(pst[0], n) == 12)
printf("全部为空位,没有可显示信息。\n");
else
{
for (i = 0; i < n - 1; i++)
{
for (j = i + 1; j < n; j++)
{
if (strcmp(pst[i]->name.first_name, pst[j]->name.first_name) == 0)
{
if (strcmp(pst[i]->name.last_name, pst[j]->name.last_name) > 0)
{
temp = pst[i];
pst[i] = pst[j];
pst[j] = temp;
}
}
else
{
if (strcmp(pst[i]->name.first_name, pst[j]->name.first_name) > 0)
{
temp = pst[i];
pst[i] = pst[j];
pst[j] = temp;
}
}
}
}
printf("当座信信息如下:\n");
for (i = 0; i < n; i++)
if (pst[i]->ide)
printf("%s.%s  %d\n", pst[i]->name.first_name, pst[i]->name.last_name, pst[i]->number);
}

}
void d(asi * pst, int n)
{
int i;
char ch;
asi temp;

if (empty_count(pst, n) == 0)
printf("预定已满没有空位。\n");
else
{
printf("请在下列空的座位号码中选择你想要的位置:\n");
empty_num(pst, n);
scanf("%d", &i);
temp = pst[i - 1];
printf("请输入你的姓名:");
scanf("%s%s", pst[i - 1].name.first_name, pst[i-1].name.last_name);
while (getchar() != '\n')
;
printf("即将为%s.%s分配%d号座位,确认请输入y 取消并退出请输入n.\n",
pst[i - 1].name.first_name, pst[i - 1].name.last_name, i);

ch = get_ch("yn");
if (ch == 'n')
pst[i - 1] = temp;
else
{
pst[i - 1].ide = true;
printf("信息已保存。\n");
}
}
}
void e(asi * pst, int n)
{
int i, j;
asi temp = { 0, false, { { '\0' }, { '\0' } } };

if (empty_count(pst, n) > 0)
{
printf("以下是可删除的信息,请输入要删除的座位号码:\n");
for (i = 0; i < n; i++)
{
if (pst[i].ide)
printf("座位:%d  姓名:%s.%s\n",
i + 1, pst[i].name.first_name, pst[i].name.last_name);
}
while (scanf("%d", &j), !pst[j - 1].ide)
printf("请输入正确的座位号码:\n");
while (getchar() != '\n')
;
printf("即将删除: 姓名:%s.%s 座位:%d,确认请输入y 取消并退出请输入n.\n",
pst[j - 1].name.first_name, pst[j - 1].name.last_name, i);
char ch = get_ch("yn");
if (ch == 'y')
{
pst[j - 1] = temp;
pst[j - 1].number = j;
printf("删除成功\n");
}

}
else
printf("所有座位都为空,没有可删除的信息。");
}


9.
巨人航空公司(见第8题)需要另一架飞机(同样容量),并使它每天服务4个航班(航班102、
311、444和519)。把程序扩展为能够处理4个航班。有一个顶层菜单可供选择航班和退出。选择
了一个特定的航班,就会调出和第7题相似的菜单,但要加上一个新选项:确认一个座位分配;并
用一个退回顶层菜单的选项代替退出选项。每个显示要指时现在正在处理哪个航班。座位分配显示
必须指时状态
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# define LEN 14
# define ALLSEATS 12
# define ALLAIR 4
# define MENU_SEAT 6
# define EMPTY 0
# define TAKNE 1
# define CONTINUE 0
# define DONE 1

struct airseat {
int seat_id;
int status;
char lastname[LEN];
char firstname[LEN];
};

struct air {
int air_id;
struct airseat place[ALLSEATS];
};

int getlet(const char * s);
int menu_1(void);
int menu_2(int flight);
void reserving(int, struct air *);
int show_empty(const struct air *, int);
void makelist(const struct air *, char *, int, int);
void show_emptylist(const struct air *, int);
void show_assignlist(const struct air *, int);
void assign_seat(struct air *, int);
void delete_seat(struct air *, int);

int main(void)
{
FILE * fp;
char choice;
struct air plane[ALLAIR];
size_t size = sizeof(struct air);

if ((fp = fopen("air.dat", "rb")) == NULL)
{
int i, j;
for (i = 0; i < 4; i++)
{
switch (i)
{
case 0: plane[i].air_id = 101; break;
case 1: plane[i].air_id = 311; break;
case 2: plane[i].air_id = 444; break;
case 3: plane[i].air_id = 519; break;
}
for (j = 0; j < 12; j++)
{
plane[i].place[j].seat_id = j + 1;
plane[i].place[j].status = EMPTY;
}
}
}
else
{
fread(plane, size, ALLAIR, fp);
fclose(fp);
}

while ((choice = menu_1()) != 'q')
{
switch (choice)
{
case 'a':reserving(plane[0].air_id, plane);
break;
case 'b':reserving(plane[1].air_id, plane);
break;
case 'c':reserving(plane[2].air_id, plane);
break;
case 'd':reserving(plane[3].air_id, plane);
break;
}
}

if ((fp = fopen("air.dat", "wb")) != NULL)
{
fwrite(plane, size, ALLAIR, fp);
fclose(fp);
}
else
puts("文件未打开,数据未保存到文件中");
puts("谢谢您的使用,再见!");

return 0;
}
int getlet(const char * s)
{
char c;
c = getchar();
while (strchr(s, c) == NULL)
{
printf("请输入正确的选择(%s):\n", s);
while (getchar() != '\n')
continue;
c = getchar();
}
while (getchar() != '\n')
continue;
return c;
}
int menu_1(void)
{
int i;
char flight_choice[ALLAIR + 2] = { "abcdq" };
char * flightlist[ALLAIR + 1] = {
"101: 7:30", "311: 10:00", "444: 15:30", "519: 22:00", "Quit"
};
puts("欢迎乘做巨人航空,您可以选择下列航班:");
for (i = 0; i <= ALLAIR; i++)
printf("%c: %s\n", flight_choice[i], flightlist[i]);

return getlet(flight_choice);
}
int menu_2(int flight)
{
int i;
char seats_choice[MENU_SEAT + 1] = { "abcdef" };
char * choicelist[6] = {
"显示当前航班还有多少座位可预定",
"显示可预定的坐位编号",
"显示已预定的坐位信息",
"提交新的预定信息",
"删除预定信息",
"返回上级菜单",
};
printf("\n欢迎乘座巨人航空%d航班,请根据选项查看座位信息\n", flight);
for (i = 0; i < MENU_SEAT; i++)
printf("%c): %s\n", seats_choice[i], choicelist[i]);
return getlet(seats_choice);
}
void reserving(int flight, struct air *p)
{
int choice_f;
int i;
int loop = 1;

switch (flight)
{
case 101: i = 0; break;
case 311: i = 1; break;
case 444: i = 2; break;
case 519: i = 3; break;
}
while (loop && ((choice_f = menu_2(flight)) != 'q'))
{
switch (choice_f)
{
case 'a': printf("本次航班还有%d个空位可预定\n", show_empty(p, i));
break;
case 'b': show_emptylist(p, i);
break;
case 'c': show_assignlist(p, i);
break;
case 'd': assign_seat(p, i);
break;
case 'e': delete_seat(p, i);
break;
}
if (choice_f == 'f')
loop = 0;
}
}
int show_empty(const struct air *p, int i)
{
int j;
int count = 0;
for (j = 0; j < ALLSEATS; j++)
if (p[i].place[j].status == EMPTY)
count++;
return count;
}
void makelist(const struct air *p, char * str, int i, int statu)
{
char temp[LEN];
int j;
str[0] = '\0';
for (j = 0; j < ALLSEATS; j++)
if (p[i].place[j].status == statu)
{
sprintf(temp, " %d", p[i].place[j].seat_id);
strcat(str, temp);
}
}
void show_emptylist(const struct air *p, int i)
{
char emptylist[3 * ALLSEATS];
if (show_empty(p, i) == EMPTY)
printf("%d航班所有座位都已被预定。\n", p[i].air_id);
else
{
printf("%d航班有下列座位可预定:\n", p[i].air_id);
makelist(p, emptylist, i, EMPTY);
puts(emptylist);
}
}
void show_assignlist(const struct air *p, int i)
{
int j;
if (show_empty(p, i) == ALLSEATS)
printf("%d航班还没有座位被预定。\n", p[i].air_id);
else
{
printf("%d航班已经预定的座位短信息如下:\n", p[i].air_id);
for (j = 0; j < ALLSEATS; j++)
if (p[i].place[j].status == TAKNE)
{
printf("seat %d : %s, %s\n",
p[i].place[j].seat_id, p[i].place[j].firstname, p[i].place[j].lastname);
}
}
}
void assign_seat(struct air *p, int i)
{
char list[3 * ALLSEATS];
int seat, loop;
if (show_empty(p, i) == EMPTY)
printf("%d航班所有座位都已被预定。\n", p[i].air_id);
else
{
makelist(p, list, i, EMPTY);
puts("请根据空位列表输入你要预订的座位:");
puts(list);
do
{
while (scanf("%d", &seat) != 1)
{
scanf("%*s");
puts("请根据空位列表输入你要预订的座位:");
puts(list);
}
while (getchar() != '\n')
continue;
if (seat < 1 || seat > ALLSEATS || p[i].place[seat - 1].status == TAKNE)
{
puts("请根据空位列表输入你要预订的座位:");
puts(list);
loop = DONE;
}
else
loop = CONTINUE;
} while (loop);
puts("请输入您的姓:");
gets(p[i].place[seat - 1].firstname);
puts("请输入您的名:");
gets(p[i].place[seat - 1].lastname);
puts("您的预定信息如下:");
printf("seat %d: %s, %s\n",
p[i].place[seat - 1].seat_id, p[i].place[seat - 1].lastname, p[i].place[seat - 1].firstname);
puts("输入字母a保存,输入字母d取消保存");
if (getlet("ad") == 'a')
{
p[i].place[seat - 1].status = TAKNE;
puts("您的预定信息已保存。");
}
else
puts("您的预定未完成。");
}
}
void delete_seat(struct air *p, int i)
{
char list[3 * ALLSEATS];
int seat, loop;
if (show_empty(p, i) == ALLSEATS)
printf("%d航班所有座位为空。\n", p[i].air_id);
else
{
makelist(p, list, i, TAKNE);
puts("请根据空位列表输入你要预订的座位:");
puts(list);
do
{
while (scanf("%d", &seat) != 1)
{
scanf("%*s");
puts("请根据空位列表输入你要预订的座位:");
puts(list);
}
while (getchar() != '\n')
continue;
if (seat < 1 || seat > ALLSEATS || p[i].place[seat - 1].status == EMPTY)
loop = DONE;
else
loop = CONTINUE;
} while (loop);
puts("您要删除的预定信息如下:");
printf("seat %d: %s, %s\n",
p[i].place[seat - 1].seat_id, p[i].place[seat - 1].lastname, p[i].place[seat - 1].firstname);
puts("输入字母d确认删除,输入字母e取息保存");
if (getlet("ed") == 'd')
{
p[i].place[seat - 1].status = EMPTY;
puts("您选择的的预定信息已删除。");
}
else
puts("取消。");
}
}


10. 编写一个程序,用指向函数的指针数组执行菜单。例如,在菜单中选择a 会激活由数组第一个元
素指向的函数。
#include <stdio.h>
#include <string.h>
void a(void);
void b(void);
void c(void);
void d(void);
int menu(void);
int getlet(char * str);
int main(void)
{
//定义一个函数指针数组
void(*fun[4])(void) = {a, b, c, d};
//定义一个函数指针
void(*f)();

char ch;
while ((ch = menu()) != 'q')
{
//使用函数指针数组
printf("%p\n", fun[ch -'a']);
fun[ch - 'a']();
//使用函数指针
switch (ch)
{	//把函数名赋给函数指针,表示把函数的首地址赋给函数指针
case 'a': f = a;
break;
case 'b': f = b;
break;
case 'c': f = c;
break;
case 'd': f = d;
break;
default:printf("\nError!\n");
}
f();
printf("\n");
}
printf("结束。\n");
return 0;
}
int menu(void)
{
puts("生来徬徨歌词:");
puts("a)心伤烂");
puts("b)梦破败");
puts("c)骨折断");
puts("d)爱破灭");
puts("q)退出程序");

return getlet("abcdq");
}
int getlet(char * str)
{
char c;
while (c = getchar())
{
while (getchar() != '\n')
;
if (strchr(str, c) == NULL)
printf("Please enter (%s)\n", str);
else
break;
}
return c;
}
void a(void)
{
printf("1.这生活会把你的心伤烂 ");
printf("可它从来就不会有一丝怜悯 ");
printf("再也别象个傻瓜一样的哭了\n");
}
void b(void)
{
printf("2.这世界会将你的梦破败 ");
printf("而它从来就不会有一丝同情 ");
printf("再也别象个疯子一样的拼了\n");
}
void c(void)
{
printf("3.这生活会把你的骨折断 ");
printf("而它从来就只是在袖手旁观 ");
printf("不如象一块石头一样的滚吧\n");
}
void d(void)
{
printf("4.这世界会将你的爱破灭 ");
printf("而它从来就不会给一次拯救 ");
printf("不如让我们一起放任自流吧\n");
}


11. 编写一个transform()函数,它接受4个参数 :包含double类型数据的源数组名,double类型的目标数组名,表示数组元素个数的int变量以及一个函数名(或者,等价的指向函数的指针)。transform()函数把指定的函数作用于源数组的每个元素,并将返回值放在目标数组中。例如:
transform(sourec, target, 100, sin);
这个函数调用把sin(source[0])赋给target[0], 等等,共有100个元素。在一个程序中测试该函数,调用4次transform(),分别使用math.h函数库中的两个函数以及自己设计的两个适合的函数作为参数。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#define MAX 20
void transform(double a[], double b[], int n, double(*fun)(double));
double a(double);
double b(double);
void show(double array[], int n);
int main(void)
{
double source[MAX], targer[MAX];
int i;

srand((unsigned)time(NULL));
for (i = 0; i < MAX; i++)
source[i] = (double)rand() /100.00 - 50.57;

show(source, MAX);
transform(source, targer, MAX, a);
show(targer, MAX);
transform(source, targer, MAX, b);
show(targer, MAX);
transform(source, targer, MAX, ceil);
show(targer, MAX);
transform(source, targer, MAX, fabs);
show(targer, MAX);

return EXIT_SUCCESS;
}
void show(double array[], int n)
{
printf("\n");
for (int i = 0; i <n; i++)
{
printf("%10.2lf ", array[i]);
if (i % 5 == 4)
printf("\n");
}
printf("\n");
}
void transform(double a[], double b[], int n, double(*fun)(double))
{
int i;
for (i = 0; i < n; i++)
b[i] = fun(a[i]);
}
double a(double fa)
{
return fa + fa;
}
double b(double fa)
{
return  fa-1;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息