第14章 结构和其他数据形式 14.18 编程练习

    1.重做复习题3,但用月份名的拼写代替月份号(别忘了可以使用strcmp())。

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

int days(char *p);

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()
{
    char input[10];
    int daytotal;

    printf("Enter the name of a month: ");
    while(gets(input)!=NULL && input[0]!='\0')
    {
        daytotal = days(input);
        if(daytotal>0)
            printf("There are %d days through %s.\n",daytotal,input);
        else
            printf("%s is not valid input.\n",input);
        printf("Next month(empty line to quit): ");
    }
    puts("bye");

    return 0;
}

int days(char *p)
{
    int i=0,total=0;
    while(p[i]!='\0')
    {
        p[i]=tolower(p[i]);
        i++;
    }

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

    return -1;
}

2、编写一个程序,请求用户输入日、月、年。月份可以是月份号、月份名或月份缩写。然后程序返回一年中到给定日子的总天数。

#include <stdio.h>

int days(int day,int month,int year);
int leapyear(int year);

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()
{
    int day=1,mon=12,year=1,daytotal;

    printf("Enter the number of day,month,year: ");
    while(scanf("%d%d%d",&day,&mon,&year)==3)
    {
        daytotal = days(day,mon,year);
        if(daytotal>0)
            printf("There are %d days through day %d,month %d,year %d.\n",daytotal,day,mon,year);
        else
            printf("day %d,mon %d,year %d is not valid input.\n",day,mon,year);
        printf("Next month(q to quit): ");
    }
    puts("bye");

    return 0;
}

int days(int day,int mon,int year)
{
    int i,total;

    if(leapyear(year)) months[1].days=29;
        else months[1].days=28;

    if(mon<1 || mon>12 || day<1 || day>months[mon-1].days)
        return -1;
    else
    {
     for(i=0,total=0;i<mon-1;i++)
            total+=months[i].days;
     return total+day;
    }
}

int leapyear(int year)
{
    if(year%400 == 0)
        return 1;
    else if(year%100 !=0 && year%4 ==0)
        return 1;
    else return 0;
}

    3.修改程序清单l4.2中的书目列表程序,使它首先按照输入的顺序输出图书的描述,然后按照标题的字母升序输出图书的描述,最后按照value值的升序输出图书的描述。

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

void sort_title (struct book *p,int count);
void sort_value (struct book *p,int count);

#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')
            continue;
        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);
        printf("Here is the list of your books by title:\n");
        sort_title(&library[0],count);
        for(index=0;index<count;index++)
            printf("%s by %s: $%.2f\n",library[index].title,
                   library[index].author,library[index].value);
        printf("Here is the list of your books by value:\n");
        sort_title(&library[0],count);
        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");
    return 0;
}

void sort_title(struct book *p,int count)
{
    int i,j;
    struct book temp;
    for(i=0;i<count-1;i++)
        for(j=0;j<count-1-i;j++)
        if(strcmp(p[j].title,p[j+1].title)>0)
    {
        temp=p[j];
        p[j]=p[j+1];
        p[j+1]=temp;
    }
}

void sort_value(struct book *p,int count)
{
    int i,j;
    struct book temp;
    for(i=0;i<count-1;i++)
        for(j=0;j<count-1-i;j++)
        if(p[j].value > p[j+1].value)
    {
        temp=p[j];
        p[j]=p[j+1];
        p[j+1]=temp;
    }
}

   4.编写一个程序。按照下列要求,创建一个含有两个成员的结构模板:

    a.第一个成员是社会保障号;第二个成员是一个含三个成员的结构。它的第一个成员是名,第二个成员是名和姓中间的名字,最后一个成员是姓。创建并初始化一个含有5个此类结构的数组。程序以下列形式输出数据:

    名和姓中间的名字只输出了它的第一个字母,后面加了一个句点。如果姓名中间的名字为空,那么它的第一个字母和句点都不会输出(当然喽)。写一个函数来实现输出,把结构数组传递给这个函数。

#include <stdio.h>

struct names {
    char firstname[20];
    char middlename[20];
    char lastname[20];
};

struct persons{
    int number;
    struct names name;
};

void display(struct persons *p);

struct persons person[5]={
    {302039823,{"Dribble","Mackede","Flossie"}},
    {345345345,{"gadenfs","Kasdfas","Pszajkh"}},
    {302039823,{"Kazsdfj","Aasdfaf","Mjasdfh"}},
    {302039823,{"Qaadsef","","Yjsjdsh"}},
    {302039823,{"Bsdsdfs","Fsjdsdd","Rshdsdf"}}
};

int main(void)
{
    display(person);
    return 0;
}

void display(struct persons *p)
{
    int i;
    for(i=0;i<5;i++)
        if(p[i].name.middlename[0]!='\0')
        printf("%s,    %s    %c. --%d\n",p[i].name.firstname,
               p[i].name.lastname,p[i].name.middlename[0],p[i].number);
        else
        printf("%s,  %s --%d\n",p[i].name.firstname,p[i].name.lastname,
               p[i].number);
}

    b.修改a部分,传递结构的值而不是结构地址。

#include <stdio.h>

struct names {
    char firstname[20];
    char middlename[20];
    char lastname[20];
};

struct persons{
    int number;
    struct names name;
};

void display(struct persons people[]);

struct persons person[5]={
    {302039823,{"Dribble","Mackede","Flossie"}},
    {345345345,{"gadenfs","Kasdfas","Pszajkh"}},
    {302039823,{"Kazsdfj","Aasdfaf","Mjasdfh"}},
    {302039823,{"Qaadsef","","Yjsjdsh"}},
    {302039823,{"Bsdsdfs","Fsjdsdd","Rshdsdf"}}
};

int main(void)
{
    display(person);
    return 0;
}

void display(struct persons people[5])
{
    int i;
    for(i=0;i<5;i++)
        if(people[i].name.middlename[0]!='\0')
        printf("%s,    %s    %c. --%d\n",people[i].name.firstname,
               people[i].name.lastname,people[i].name.middlename[0],people[i].number);
        else
        printf("%s,  %s --%d\n",people[i].name.firstname,people[i].name.lastname,
               people[i].number);
}

5.写一个程序,满足下列要求:

    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 <stdio.h>
#define CSIZE 4
#define SCORE 3

struct name {
 char firstname[20];
 char secondname[20];
};

struct student {
 struct name names;
 float score[SCORE];
 float average;
};

void get_score(struct student *p);
void calculate_average(struct student *p);
void print_each(struct student *p);
void print_class_average(struct student *p);

int main()
{
 struct student students[CSIZE]={
  { {"Aasdda", "Basdjas"}, 0, 0, 0, 0 },
  { {"Csdfss", "Ddsfsdd"}, 0, 0, 0, 0 },
  { {"Edfdsf", "Fsfdsfd"}, 0, 0, 0, 0 },
  { {"Gfdsse", "Hservvd"}, 0, 0, 0, 0 }
 };

 printf("selcet function: d, e, f, g\n");
 printf("d: acquire scores for each student\n");
 printf("e: Calculate the average score value for each structure and assign it to the proper member\n");
 printf("f: Print the information in each structure\n");
 printf("g: Print the class average for each of the numeric structure members\n");
 while(1)
 {
  switch ( getchar() )
  {
   case 'd' : get_score(students); break;
   case 'e' : calculate_average(students); break;
   case 'f' : print_each(students); break;
   case 'g' : print_class_average(students); break;
   case '\n' : break;
   default  : puts("Bye"); return 0;
  }
 }
}

void get_score(struct student *p)
{
 int i,j;
 for (i = 0; i < CSIZE; i++)
 {
  printf("input the %d scores of %s %s:", SCORE, (p+i)->names.firstname, (p+i)->names.secondname);
  for (j=0; j<SCORE; j++)
   scanf("%f", &( (p+i)->score[j] ) );
 }
 printf("input finished!\n");
}

void calculate_average(struct student *p)
{
 int i,j;
 float total;
 for (i = 0; i < CSIZE; i++)
 {
  for (j=0,total=0; j<SCORE; j++)
   total += (p+i)->score[j] ;
  (p+i)->average = total / SCORE ;
 }
 printf("calculate finished!\n");
}


void print_each(struct student *p)
{
 int i,j;
 float total;
 for (i = 0; i < CSIZE; i++)
 {
  printf("%s %s:\t", (p+i)->names.firstname, (p+i)->names.secondname);
  for (j=0,total=0; j<SCORE; j++)
   printf("score%d: %g\t", j+1, (p+i)->score[j]);
  printf("average: %g\n", (p+i)->average);
 }
}

void print_class_average(struct student *p)
{
 int i;
 float total;
 for (i = 0, total=0; i < CSIZE; i++)
   total += (p+i)->average ;
 printf("class average: %g\n", total / CSIZE);
}

6.一个文本文件中存放着一个棒球队的信息。每一行的数据都是这样排列的:

  4 Jessie Joybat 5 2 1 1

    第一项是球员号码,为了方便,范围是0到18。第二项是球员的名,第三项是姓。姓和名都是单个的单词。下一项是官方统计的球员上场次数,紧跟着是击中数、走垒数和跑点数( RBI)。文件可能包括超过一场比赛的数据,因此同一个球员可能会有多于一行的数据,而且在不同的行之间有可能有别的球员的数据。写一个程序,把这些数据存储到一个结构数组中。结构中必须含有姓、名、上场次数、击中数、走垒数和跑点数,以及击球平均成功率(稍后计算)。可以使用球员号码作为数组索引。程序应该读到文件末尾,并且应该保存每个球员的累计总和。

    这个棒球运动中的统计方法是相关的。例如,一次走垒和触垒中的失误并不会记作上场次数,但是这可能产生一个RBI。可是,该程序所要做的只是处理数据文件,而不必关心数据的实际含义。

    要实现这些功能,最简单的方法是把结构的内容初始化为零值,将文件数据读入临时变量中,然后把它们加到相应结构的内容中。程序读完文件后,应该计算每个球员的击球平均成功率,并把它保存到相应的结构成员里。计算击球平均成功率是用球员的累计击中数除以上场累计次数;这是个浮点数计算。然后程序要显示每个球员的累计数据,并且对整个时期显示一行综合统计数据。

//中文版的此题最后一句说“并且对整个时期显示一行综合统计数据”

//从英文原版来看,“时期”应为“队伍”(team)

#include <stdio.h>
#include <string.h>
#define MAX 10

struct member {
    char firstname[10];
    char lastname[10];
    int bat;
    int hit;
    int walk;
    int RBI;
    float average;
};

void clear(struct member *p);
void get_info(struct member *p);
void cal_average(struct member *p);
void display(struct member *p);

int main(void)
{
    struct member members[MAX];
    clear(members);  //清空结构数组
    get_info(members);
    cal_average(members);
    display(members);

    return 0;
}

void clear(struct member *p)
{
    int i;
    for(i=0;i<MAX;i++)
    {
        strcpy(p[i].firstname,"");  //把字符变量置空
        strcpy(p[i].lastname,"");
        p[i].bat=0;
        p[i].hit=0;
        p[i].walk=0;
        p[i].RBI=0;
        p[i].average=0;
    }
}

void get_info(struct member *p)
{
    int number,bat,hit,walk,RBI;
    char firstname[20],lastname[20],filename[20]="c:\\info.txt";
    FILE *fp;
    printf("input the file name: ");
    scanf("%s",filename);
    while((fp=fopen(filename,"r"))==NULL)
    {
        printf("cannot open filename.input again: ");
        scanf("%s",filename);
    }
    while(fscanf(fp,"%d %s %s %d %d %d %d\n",&number,firstname,lastname,
                 &bat,&hit,&walk,&RBI)==7)
    {
        strcpy(p[number].firstname,firstname);
        strcpy(p[number].lastname,lastname);
        p[number].bat+=bat;
        p[number].hit+=hit;
        p[number].walk+=walk;
        p[number].RBI+=RBI;
    }
    fclose(fp);
}

void cal_average(struct member *p)
{
    int i;
    for(i=0;i<MAX;i++)
        if(p[i].bat)
        p[i].average=(float)p[i].hit / (float)p[i].bat;
}

void display(struct member *p)
{
    int i;
    struct member total={"","",0,0,0,0,0};
    printf("%7s%10s%10s%5s%5s%5s%5s%10s\n","number", "firstname", "lastname", "bat", "hit", "walk", "RBI", "average");
    for(i=0;i<MAX;i++)
        if(p[i].bat)
    {
        printf("%7d%10s%10s%5d%5d%5d%5d%10g\n",i, p[i].firstname, p[i].lastname, p[i].bat, p[i].hit, p[i].walk, p[i].RBI, p[i].average);
        total.bat+=p[i].bat;
        total.hit+=p[i].hit;
        total.walk+=p[i].walk;
        total.RBI+=p[i].RBI;
    }
    if(total.bat)
        total.average=(float)total.hit / (float)total.bat ;
    printf("%27s%5d%5d%5d%5d%10g\n","total team", total.bat, total.hit, total.walk, total.RBI, total.average);
}

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

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

#define MAXTITL 40
#define MAXAUTL 40
#define MAXBKS 10

int count=0;

struct book {
    char title[MAXTITL];
    char author[MAXAUTL];
    float value;
};

void read_file(struct book *p,char * filename);
void display(struct book *p);
void change(struct book *p);
void reduce(struct book *p);
void add(struct book *p);
void write_file(struct book *p,char *str);

int main(void)
{
    struct book library[MAXBKS];
    char command[10];
    read_file(library,"book.dat");
    printf("select the functions: ");
    printf("d: display all book            c: change a book\n");
    printf("r: reduce a book               a: add books\n");
    printf("other: save and quit:");
    while(1)
    {
        gets(command);
        switch(command[0])
        {
        case 'd': display(library);break;
        case 'c': change(library);break;
        case 'r': reduce(library);break;
        case 'a': add(library);break;
        default:write_file(library,"book.dat");
        }
        printf("select: d/c/r/a/other:");
    }
}

void read_file(struct book *p,char *filename)
{
    FILE *pbooks;
    if((pbooks=fopen(filename,"a+b"))==NULL)
    {
        printf("Can't open %s file.",filename);
        exit(1);
    }
    rewind(pbooks);
    while(count<MAXBKS && fread(p+count,sizeof(struct book),1,filename)==1)
        count++;
    fclose(pbooks);
    printf("Read %s successfully! There are %d books.",filename,count);
}

void display(struct book *p)
{
    int i;
    if(count==0)printf("There is no book!\n");
    printf("book list for %d books.\n",count);
    for(i=0;i<count;i++)
        printf("%s by %s : $%.2f\n",p[i].title,p[i].author,p[i].value);
}

void change(struct book *p)
{
    char title[MAXTITL];
    int i;

    printf("input the name of the book,which you want to change: ");
    gets(title);

    for(i=0;i<count;i++)
        if(strcmp(p[i].title,title)==0)
    {
        puts("please add a new title: ");
        gets(p[i].title);
        puts("Now input the author: ");
        gets(p[i].author);
        puts("Now enter the valur: ");
        scanf("%f",&p[i].value);
        getchar();
        puts("the book has been changed!");
    }
    printf("error!the book is not in the list.\n");
    return;
}

void reduce(struct book *p)
{
    int i;
    char title[MAXTITL];

    if(count==0)
        {
        printf("error!book list is empty!\n");
        return;
        }
    printf("input the name of the book which you want to reduce: ");
    gets(title);
    for(i=0;i<count;i++)
        if(strcmp(p[i].title,title)==0)
    {
        p[i]=p[count-1];
        strcpy(p[count-1].title,"");
        strcpy(p[count-1].author,"");
        p[count-1].value=0;
        count--;
        printf("%s has been delete from book list.\n",title);
        return;
    }
    printf("error!%s is not in book list.\n",title);
    return;
}

void add(struct book *p)
{
    if(count==MAXBKS)
    {
        fputs("error!the book list is full.",stderr);
        return;
    }

    puts("Please add new book title");
    puts("please enter at the start of a line to stop.");
    while(count<MAXBKS && gets(p[count].title)!=NULL && p[count].title[0]!='\0')
    {
        puts("Now enter the author.");
        gets(p[count].author);
        puts("Now enter the value.");
        scanf("%f",&p[count++].value);
        getchar();
        if(count<MAXBKS)
            puts("Enter the next title.");
        else
            puts("The book list file is full.");
    }
}

void write_file(struct book *p,char *str)
{
    FILE *pbooks;
    pbooks = fopen(str,"wb");
    pbooks = fopen(str,"r+b");
    fwrite(p,sizeof(struct book),count,pbooks);
    fclose(pbooks);
}

 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>

#define MAX 12

struct seat {
    int number;
    int assign;
    char lastname[10];
    char firstname[10];
    };

void read_file(struct seat *p,char *filename);
void choose(void);
void show_number_empty(struct seat *p);
void show_list_empy(struct seat *p);
void show_list(struct seat *p);
void assign_seat(struct seat *p);
void delete_seat(struct seat *p);
void write_file(struct seat *p,char * filename);

struct seat seats[MAX]={   //设置缺省
 {101,0},
 {102,0},
 {103,0},
 {104,0},
 {105,0},
 {106,0},
 {107,0},
 {108,0},
 {109,0},
 {110,0},
 {111,0},
 {112,0}
};

int main(void)
{
    read_file(seats,"seat.dat");
    choose();
    return 0;  //此句无用
}

void read_file(struct seat *p,char *filename)
{
    FILE *pseats;
    if((pseats=fopen(filename,"rb"))==NULL)
        printf("Can't open %s file.So load default date.\n",filename);
    else
    {
        rewind(pseats);
        while(fread(p,sizeof(struct seat),MAX,pseats)==1)
            continue;
        fclose(pseats);
        printf("read %s successfully!\n",filename);
    }
}

void choose(void)
{
    char command[10];
    printf("\nTo choose a function,enter it's letter label:\n");
    printf("a) Show number of empty seats\n");
    printf("b) Show list of empty seats\n");
    printf("c) Show alphabetical list of seats\n");
    printf("d) Assign a customer to a seat assignment\n");
    printf("e) Delete a seat assignment\n");
    printf("f) Quit\n");
    gets(command);
    switch(command[0])
    {
        case 'a':show_number_empty(seats); break;
        case 'b':show_list_empy(seats); break;
        case 'c':show_list(seats);break;
        case 'd':assign_seat(seats);break;
        case 'e':delete_seat(seats);break;
        default:write_file(seats,"seat.dat");
        puts("Quit");
        exit(1);
    }
}

void show_number_empty(struct seat *p)
{
    int i,n;
    for(i=0,n=0;i<MAX;i++)
        if(p[i].assign==0)
        n++;
    printf("There are %d empty seats.\n",n);
}

void show_list_empy(struct seat *p)
{
    int i;
    printf("empty seats:\n");
    for(i=0;i<MAX;i++)
        if(p[i].assign==0)
        printf("number %d\n",p[i].number);
}

void show_list(struct seat *p)
{
    int i;
    printf("seat list:\n");
    for(i=0;i<MAX;i++)
    {
        printf("number %d\t",p[i].number);
        if(p[i].assign==1)
            printf("full %s %s\n",p[i].firstname,p[i].lastname);
        else
            printf("empty\n");
    }
}

void assign_seat(struct seat *p)
{
    int number,i;
    printf("Input the seat number:");
    scanf("%d",&number);
    getchar();
    for(i=0;i<MAX;i++)
        if(p[i].number==number)
    {
        if(p[i].assign==1)
            printf("NO.%d seat is already assigned!\n",p[i].number);
        else
        {
            printf("Input firstname of the holder:");
            scanf("%s",p[i].firstname);
            printf("Input lastname of the holder:");
            scanf("%s",p[i].lastname);
            getchar();
            p[i].assign=1;
            printf("assign NO.%d seat successfully!\n",p[i].number);
        }
        return;
    }
    printf("%d is a invalid seat number!",number);
}

void delete_seat(struct seat *p)
{
    int number,i;
    printf("Input the seat number:");
    scanf("%d",&number);
    getchar();
    for(i=0;i<MAX;i++)
    if(p[i].number==number)
    {
        if(p[i].assign==0)
            printf("NO.%d seat is already empty!\n");
        else
        {
            p[i].assign==0;
            printf("delete NO.%d seat successfully!\n",number);
        }
        return;
    }
    printf("%d is a invalid seat number\n",number);
}

void write_file(struct seat *p,char *filename)
{
    FILE *pseats;
    if((pseats=fopen(filename,"wb"))==NULL)
    {
        printf("Can't open %s file.",filename);
        exit(1);
    }
    fwrite(p,sizeof(struct seat),MAX,pseats);
    fclose(pseats);
}

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

#include <stdio.h>
#include <stdlib.h>

#define FLIGHT 4
#define SEAT 12

struct seat {
    int number;
    int assign;
    char lastname[10];
    char firstname[10];
    };
struct flight{
    int number;
    struct seat seats[SEAT];
};
struct flight flights[4]={
    {102},
    {311},
    {444},
    {519}
};

void read_file(struct flight *p,char *filename);
void load_data(struct flight *p);
int choose_flight(void);
int choose_command(struct flight *p);
void show_number_empty(struct seat *p);
void show_list_empy(struct seat *p);
void show_list(struct seat *p);
void assign_seat(struct seat *p);
void delete_seat(struct seat *p);
void confirm_seat(struct seat *p);
void write_file(struct flight *p,char * filename);

int main(void)
{
    int n;
    read_file(flights,"seat.dat");
    while(1)
    {
        n=choose_flight();
        if(n<0 || n>=FLIGHT) break;
        while(choose_command(&flights[n])) continue;
    }
    write_file(flights,"seat.dat");
    puts("Quit");
    return 0;  //此句无用
}

void read_file(struct flight *p,char *filename)
{
    FILE *pseats;
    if((pseats=fopen(filename,"rb"))==NULL)
        {
            printf("Can't open %s file.So load default date.\n",filename);
            load_data(p);
        }
    else
    {
        rewind(pseats);
        while(fread(p,sizeof(struct flight),FLIGHT,pseats)==1)
            continue;
        fclose(pseats);
        printf("read %s successfully!\n",filename);
    }
}

void load_data(struct flight *p) //载入默认数据
{
    int i,j;
    for(i=0;i<FLIGHT;i++)
        for(j=0;j<SEAT;j++)
    {
        p[i].seats[j].number=i*100+j;//按实际情况设置座位号
        p[i].seats[j].assign=0;
    }
}

int choose_flight(void) //返回航班下标
{
    char command[10];
    printf("\nTo choose a flight,enter its letter label:\n");
    printf("a) Flights 102\n");
    printf("b) Flights 311\n");
    printf("c) Flights 444\n");
    printf("d) Flights 519\n");
    printf("e) Quit\n");
    gets(command);
    switch (command[0])
    {
        case 'a' : return 0;
        case 'b' : return 1;
        case 'c' : return 2;
        case 'd' : return 3;
        default  : return 4;
    }
}

int choose_command(struct flight *p)
{
    char command[10];
    printf("\nFlight %d:\n",p->number);
    printf("To choose a function,enter it's letter label:\n");
    printf("a) Show number of empty seats\n");
    printf("b) Show list of empty seats\n");
    printf("c) Show alphabetical list of seats\n");
    printf("d) Assign a customer to a seat assignment\n");
    printf("e) Delete a seat assignment\n");
    printf("f) Confirm a seat assignment\n");
    printf("g) Exit to the top-level munu\n");
    gets(command);
    switch(command[0])
    {
        case 'a':show_number_empty(p->seats); return 1;
        case 'b':show_list_empy(p->seats); return 1;
        case 'c':show_list(p->seats);return 1;
        case 'd':assign_seat(p->seats);return 1;
        case 'e':delete_seat(p->seats);return 1;
        case 'f': confirm_seat( p->seats );  return 1;
        default:return 0;
    }
}

void show_number_empty(struct seat *p)
{
    int i,n;
    for(i=0,n=0;i<SEAT;i++)
        if(p[i].assign==0)
        n++;
    printf("There are %d empty seats.\n",n);
}

void show_list_empy(struct seat *p)
{
    int i;
    printf("empty seats:\n");
    for(i=0;i<SEAT;i++)
        if(p[i].assign==0)
        printf("number %d\n",p[i].number);
}

void show_list(struct seat *p)
{
    int i;
    printf("seat list:\n");
    for(i=0;i<SEAT;i++)
    {
        printf("number %d\t",p[i].number);
        if(p[i].assign==1)
            printf("full %s %s\n",p[i].firstname,p[i].lastname);
        else
            printf("empty\n");
    }
}

void assign_seat(struct seat *p)
{
    int number,i;
    printf("Input the seat number:");
    scanf("%d",&number);
    getchar();
    for(i=0;i<SEAT;i++)
        if(p[i].number==number)
    {
        if(p[i].assign==1)
            printf("NO.%d seat is already assigned!\n",p[i].number);
        else
        {
            printf("Input firstname of the holder:");
            scanf("%s",p[i].firstname);
            printf("Input lastname of the holder:");
            scanf("%s",p[i].lastname);
            getchar();
            p[i].assign=1;
            printf("assign NO.%d seat successfully!\n",p[i].number);
        }
        return;
    }
    printf("%d is a invalid seat number!",number);
}

void delete_seat(struct seat *p)
{
    int number,i;
    printf("Input the seat number:");
    scanf("%d",&number);
    getchar();
    for(i=0;i<SEAT;i++)
    if(p[i].number==number)
    {
        if(p[i].assign==0)
            printf("NO.%d seat is already empty!\n",number);
        else
        {
            p[i].assign=0;
            printf("delete NO.%d seat successfully!\n",number);
        }
        return;
    }
    printf("%d is a invalid seat number\n",number);
}

void confirm_seat(struct seat *p)
{
 int number, i;
 printf("Input the seat number:");
 scanf("%d", &number);
 getchar();
 for (i=0; i<SEAT; i++)
  if( p[i].number == number)
  {
   if (p[i].assign == 0)
    printf("NO.%d seat is empty!\n", number);
   else
    printf("NO.%d seat is assigned! its holder is %s %s\n", number, p[i].firstname, p[i].lastname);
   return;
  }
 printf("%d is a invalid seat number\n", number);
}

void write_file(struct flight *p,char *filename)
{
    FILE *pseats;
    if((pseats=fopen(filename,"wb"))==NULL)
    {
        printf("Can't open %s file.",filename);
        exit(1);
    }
    fwrite(p,sizeof(struct seat),SEAT*FLIGHT,pseats);
    fclose(pseats);
}

10、编写一个程序 ,用指向函数的指针数组来执行菜单。例如,在菜单中选择a,会激活由数组第一个元素指向的函数 。

#include <stdio.h>

#define F 4

float add(float x, float y);
float subtract(float x, float y);
float multiply(float x, float y);
float divide(float x, float y);

int main(void)
{
 char command[5];
 float x, y;
 float (*p[F])(float x, float y) = {add, subtract, multiply, divide};
 while(1)
 {
  printf("Select function:\n");
  printf("1 :  x + y\n");
  printf("2 :  x - y\n");
  printf("3 :  x * y\n");
  printf("4 :  x / y\n");
  printf("q :  quit\n");
  gets(command);
  if ( command[0] < '1' ||  command[0] > '4' ) break;
  printf("input x, y:");
  scanf("%f%f", &x, &y);
  getchar();
  printf("result is : %g\n", (*p[ command[0] - '1' ]) (x,y) );
 }
 return 0;
}


float add(float x, float y)
{
 return x + y ;
}

float subtract(float x, float y)
{
 return x - y ;
}

float multiply(float x, float y)
{
 return x * y ;
}

float divide(float x, float y)
{
 return x / y ;
}

11.编写—个transform()函数,它接受4个参数:包含double类型数据的源数组名,double类型的目标数组名,表示数组元素个数的int变量以及一个函数名(或者,等价的指向函数的指针)。transform()函数把指定的函数作用于源数组的每个元素,并将返回值放到目标数组中。例如:

    transform(source, target, 100, sin);

 

    这个函数调用把sin(source[0])赋给target[O),等等,共有100个元素。在一个程序中测试该函数,调用4次transform(),分别使用math.h函数库中的两个函数以及自己设计的两个适合的函数作为参数。

#include <stdio.h>
#include <math.h>

#define M 10

void transform(double[],double[],int,double(*)(double));
double reciprocal(double x);
double negative(double x);

int main(void)
{
    double source[M],target[M];
    int i;
    for(i=0;i<M;i++)
        source[i]=i;

    printf("sin:\n");
    transform(source,target,M,sin);
    for(i=0;i<M;i++)
        printf("%g -> %g ,",source[i],target[i]);

    printf("\n\nexp:\n");
    transform(source,target,M,exp);
    for(i=0;i<M;i++)
        printf("%g -> %g , ",source[i],target[i]);

    printf("\n\nreciprocal:\n");
    transform(source,target,M,reciprocal);
    for(i=0;i<M;i++)
        printf("%g -> %g , ",source[i],target[i]);

    printf("\n\nnegative:\n");
    transform(source,target,M,negative);
    for(i=0;i<M;i++)
        printf("%g -> %g , ",source[i],target[i]);

    printf("\n");
    return 0;
}

void transform(double source[],double target[],int n,double (*p)(double))
{
    int i;
    for(i=0;i<n;i++)
        target[i]=(*p)(source[i]);
}

double reciprocal(double x)
{
    return 1/x;
}

double negative(double x)
{
    return -x;
}

 

转载于:https://my.oschina.net/idreamo/blog/913599

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值