C Primer Plus--- Chapter 14---Structures and Other Data Forms ---11.练习题

C Primer Plus--- Chapter 14---Structures and Other Data Forms ---11.练习题

  • 1. Redo Review Question 5, but make the argument the spelled-out name of the month instead of the month number. (Don’t forget about strcmp().) Test the function in a simple program.
  • 2. Write a program that prompts the user to enter the day, month, and year. The month can be a month number, a month name, or a month abbreviation. The program then should return the total number of days in the year up through the given day. (Do take leap years into account.)
  • 3. Revise the book-listing program in Listing 14.2 so that it prints the book descriptions in the order entered, then alphabetized by title, and then in order of increased value.
  • 4. Write a program that creates a structure template with two members according to the following criteria:
  • 5. Write a program that fits the following recipe:
  • 6. A text file holds information about a softball team. Each line has data arranged as follows:
  • 7. Modify Listing 14.14 so that as each record is read from the file and shown to you, you are given the chance to delete the record or to modify its contents.
  • 8. The Colossus Airlines fleet consists of one plane with a seating capacity of 12. It makes one flight daily. Write a seating reservation program with the following features:
  • 9. Colossus Airlines (from exercise 8) acquires a second plane (same capacity) and expands its service to four flights daily (Flights 102, 311, 444, and 519).
  • 10. Write a program that implements a menu by using an array of pointers to functions. For instance, choosing a from the menu would activate the function pointed to by the first element of the array.
  • 11. Write a function called transform() that takes four arguments: the name of a source array containing type double data, the name of a target array of type double, an int representing the number of array elements, and the name of a function (or, equivalently, a pointer to a function). The transform() function should apply the indicated function to each element in the source array, placing the return value in the target array.

1. Redo Review Question 5, but make the argument the spelled-out name of the month instead of the month number. (Don’t forget about strcmp().) Test the function in a simple program.

程序实现功能:

  1. 根据输入的年份判断平年还是闰年
  2. 识别输入的月份英文全称和缩写
  3. 根据输入的年月输入天数
  4. 根据输入的年月日计算这一天属于这年的第几天
#include
#include
#include
void eatline(void);
char *s_gets(char *st, int n);
int get_m(char *st);
int input(int l, int h);
int day_t(int m, int d);
struct month
{
  char name[10];
  char abb[4];
  int days;
  int monum;
};
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", 31, 7},
{"August", "Aug", 31, 8},
{"September", "Sep", 30, 9},
{"October", "Oct", 31, 10},
{"November", "Nov", 30, 11},
{"December", "Dec", 31, 12}
};
int days(char *m);
int main(void)
{
  char input_m[10];//输入月份
  int days;//总共天数
  int y, m, d, d_limit, m_num;
  printf("Enter the year (greater than 0, and  invaild input to quit): ");
  while((scanf("%d", &y) == 1) && (y > 0) && getchar() == '\n')
  {
  if(((y%4==0) && (y%100!=0)) || (y%400==0))//条件为真,则为闰年
    months[1].days = 29;
  printf("Enter the month : ");
  s_gets(input_m, 10);
 if( (m_num = get_m(input_m)) == 0)
  {
    printf("Invaild input.\nBye!\n");
    return 0;
  }
    d_limit = months[m_num-1].days;
    printf("Enter the day (input between 1 to %d): ", d_limit);
    d = input(1, d_limit);//根据输入的年月,设置当月的天数限制
    days = day_t(m_num , d);
    printf("On %d.%d.%d, the year has passed for %d days.\n", y,m_num,d,days);
  printf("Input next year: ");
  }
    puts("Bye!");
    return 0;
}
void eatline(void)
{
  while(getchar() != '\n')
  continue;
}
char *s_gets(char *st, int n)
{
  char *ret_val, *find;
  ret_val = fgets(st, n, stdin);
  if(ret_val)
  {
    find = strchr(st, '\n');
    if(find)
    *find = '\0';
    else
    eatline();
  }
  return ret_val;
}
int get_m(char *st)//将输入的月份转化为数字
{
  int n;
  st[0] = toupper(st[0]);
  for(int i = 1; st[i] != '\0'; i++)
   st[i] = tolower(st[i]);
  for(int i = 1; i <= 12; i++)
      if((strcmp(st, months[i-1].name) == 0) || strcmp(st, months[i-1].abb) == 0)
      {
        n = months[i-1].monum;
	return n;
      }
   return 0;
}
int input(int l, int h)
{
  int status, n;
  int ok = 1;
  while(ok)
  {
    status = scanf("%d", &n);
    if(status != 1 || n < l || n > h || getchar() != '\n')
    {
      printf("Enter again (input between %d to %d: ",l, h);
      eatline();
      continue;
    }
    else
    return n;
  }
}
int day_t(int mon, int day)
{
  int total = 0;
  for(int i = 1; i < mon; i++)
  total += months[i-1].days;
  total += day;
  return total;
}

2. Write a program that prompts the user to enter the day, month, and year. The month can be a month number, a month name, or a month abbreviation. The program then should return the total number of days in the year up through the given day. (Do take leap years into account.)

第一题程序实现该功能

3. Revise the book-listing program in Listing 14.2 so that it prints the book descriptions in the order entered, then alphabetized by title, and then in order of increased value.

#include
#include
char *s_gets(char *st, int n);
float input_f(float n);
#define MAXTITL 40
#define MAXAUTL 40
#define MAXBKS 100
struct book
{
  char title[MAXTITL];
  char author[MAXAUTL];
  float value;
};
void sortt(struct book *pb[], int n);//在结构体声明之后
void sortv(struct book *pb[], int n);
int main(void)
{
  struct book library[MAXBKS];
  struct book *pbk[MAXBKS];
  int count = 0;
  int index;
  printf("Please enter the book title. ");
  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");
    library[count].value = input_f(0);
    pbk[count] = &library[count];
    count++;
    printf("Enter the next title.\n");
  }
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 sorted by title:\n");
sortt(pbk, 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 sorted by value:\n");
sortv(pbk, count);
for(index = 0; index < count; index++)
  printf("%s by %s: $%.2f\n", library[index].title, library[index].author,
  library[index].value);
return 0;
}
float input_f(float n)
{
  int status;
  int ok = 1;
  float f;
  while(ok)
  {
    status = scanf("%f", &f);
    if(status != 1 || f < 0 || getchar() != '\n')
    {
      printf("Enter again: ");
      while(getchar() != '\n')
      continue;
      continue;
    }
    else
    return f;
  }
}
void sortt(struct book *pb[], int n)// 简单选择排序
{
  int top, search;
  struct book *temp;
  for(top = 0; top < n-1; top++)
   for(search = top + 1; search < n; search++)
   if(strcmp(pb[search]->title, pb[top]->title) < 0)
   {
     temp = pb[search];
     pb[search] = pb[top];
     pb[top] = temp;
   }
}
void sortv(struct book *pb[], int n)
{
  int top, search;
  struct book *temp;
  for(top = 0; top < n-1; top++)
   for(search = top + 1; search < n; search++)
    if(pb[search]->value < pb[top]->value)
    {
      temp = pb[search];
      pb[search] = pb[top];
      pb[top] = temp;
    }
}
char *s_gets(char *st, int n)
{
  char *ret_val, *find;
  ret_val = fgets(st, n, stdin);
  if(ret_val)
  {
    find = strchr(st, '\n');
    if(find)
    *find = '\0';
    else:
    while(getchar() != '\n')
    continue;
  }
  return ret_val;
}

4. Write a program that creates a structure template with two members according to the following criteria:

a. The first member is a social security number. The second member is a structure with three members. Its first member contains a first name, its second member contains a middle name, and its final member contains a last name. Create and
initialize an array of five such structures. Have the program print the data in this format:

Dribble, Flossie M. –– 302039823

Only the initial letter of the middle name is printed, and a period is added. Neither the initial (of course) nor the period should be printed if the middle name member is empty.
Write a function to do the printing; pass the structure array to the function.
b. Modify part a. by passing the structure value instead of the address.
答案:

#include
#define LEN 15
struct person
{
 unsigned long long id;
 struct
 {
   char fname[LEN];
   char mname[LEN];
   char lname[LEN];
 };
};
void Print_a(struct person *ps, int n);
void Print_b(struct person p);
int main(void)
{
 struct person shebao[5] =
 {
   {302039823, {"Flossie", "Mr", "Dribble"}},
   {302039820, {"Jone", "Tim", "Carey"}},
   {302038320, {"Jean", "", "Leo"}},
   {302032332, {"Tom", "Ma", "Cruse"}},
   {302123211, {"Tom", "fa", "Mraz"}}
 };
 puts("Part a;");
 Print_a(shebao, 5);
 puts("Part b:");
 for(int i = 0; i < 5; i++)
  Print_b(shebao[i]);
  return 0;
}
void Print_a(struct person *ps, int n)
{
  for(int i = 0; i < n; i++)
  {
    if(ps[i].mname[0] == '\0')
    printf("%s, %s -- %llu\n", ps[i].lname, ps[i].fname, ps[i].id);
    else
    printf("%s, %s %c. -- %llu\n",ps[i].lname, ps[i].fname,
    ps[i].mname[0],ps[i].id);
  }
}
void Print_b(struct person p)
{
  if(p.mname[0] == '\0')
  printf("%s, %s -- %llu\n", p.lname, p.fname, p.id);
  else
  printf("%s, %s %c. -- %llu\n", p.lname, p.fname, p.mname[0],p.id);
}
Part a;
Dribble, Flossie M. -- 302039823
Carey, Jone T. -- 302039820
Leo, Jean -- 302038320
Cruse, Tom M. -- 302032332
Mraz, Tom f. -- 302123211
Part b:
Dribble, Flossie M. -- 302039823
Carey, Jone T. -- 302039820
Leo, Jean -- 302038320
Cruse, Tom M. -- 302032332
Mraz, Tom f. -- 302123211

5. Write a program that fits the following recipe:

a. Externally define a name structure template with two members: a string to hold the
first name and a string to hold the second name.
b. Externally define a student structure template with three members: a name structure, a grade array to hold three floating-point scores, and a variable to hold the average of those three scores.
c. Have the main() function declare an array of CSIZE (with CSIZE = 4) student structures and initialize the name portions to names of your choice. Use functions to perform the tasks described in parts d., e., f., and g.
d. Interactively acquire scores for each student by prompting the user with a student
name and a request for scores. Place the scores in the grade array portion of the appropriate structure. The required looping can be done in main() or in the function, as you prefer.
e. Calculate the average score value for each structure and assign it to the proper member.
f. Print the information in each structure.
g. Print the class average for each of the numeric structure members.

#include
#define LEN 15
#define SCORES 3
#define CSIZE 4
struct name 
{
  char fname[LEN];
  char lname[LEN];
};
struct student
{
  struct name person;
  float scores[SCORES];
  float mean;
};
void get_scores(struct student *a, int n);
void get_means(struct student *a, int n);
void show_class(struct student *a, int n);
void all_ave(struct student *a, int n);
int main(void)
{
  struct student class[CSIZE] =
  {
    {{"Bai", "Li"}},
    {{"Fu", "Du"}},
    {{"Wei", "Wang"}},
    {{"Shi", "Su"}}
  };
  get_scores(class, CSIZE);
  get_means(class, CSIZE);
  show_class(class, CSIZE);
  all_ave(class, CSIZE);
  return 0;
}
float input_f(int n)
{
  float f;
  int status;
  int ok = 1;
  while(ok)
  {
    status = scanf("%f", &f);
    if(status != 1 || getchar() != '\n' || f < 0)
    {
      printf("Enter again: ");
      while(getchar() != '\0')
      continue;
      continue;
    }
    else 
    return f;
  }
}
void get_scores(struct student *a, int n)
{
   for(int i = 0; i < n; i++)
   {
     printf("Please enter the score of %s %s :\n", a[i].person.fname,a[i].person.lname);
     for(int j = 0; j < SCORES; j++)
       a[i].scores[j] = input_f(0);
   }
}
void get_means(struct student *a, int n)
{
  float total = 0;
  for (int i = 0; i < n; i++)
  {
   for(int j = 0; j < SCORES; j++)
      total += a[i].scores[j];
    a[i].mean = total / SCORES;
  }
}
void show_class(struct student *a, int n)
{
  for(int i = 0; i < n; i++)
  {
    printf("%s %s: ", a[i].person.fname, a[i].person.lname);
    for(int j = 0; j < SCORES-1; j++)
    printf("%6.1f , ",a[i].scores[j]);
    printf("%6.1f; ", a[i].scores[SCORES-1]);
    printf("Average = %5.2f\n", a[i].mean);
  }
}
void all_ave(struct student *a, int n)
{
  float total = 0;
  int i;
  for (i = 0; i < SCORES; i++)
  {
    for(int j = 0; j < n; j++)
     total += a[j].scores[i];
     printf("Average score for number %d : %5.2f.\n",i+1, total/n);    
  }
  for (total = 0, i = 0; i < n; i++)
   total += a[i].mean;
   printf("class average : %5.2f.\n", total/n);
}

6. A text file holds information about a softball team. Each line has data arranged as follows:

4 Jessie Joybat 5 2 1 1

The first item is the player’s number, conveniently in the range 0–18. The second item is the player’s first name, and the third is the player’s last name. Each name is a single word. The next item is the player’s official times at bat, followed by the number of hits, walks, and runs batted in (RBIs). The file may contain data for more than one game,
so the same player may have more than one line of data, and there may be data for other players between those lines. Write a program that stores the data into an array of structures. The structure should have members to represent the first and last names, the at bats, hits, walks, and RBIs (runs batted in), and the batting average (to be calculated later). You can use the player number as an array index. The program should read to endof-file, and it should keep cumulative totals for each player.

The world of baseball statistics is an involved one. For example, a walk or reaching base on an error doesn’t count as an at-bat but could possibly produce an RBI. But all this program has to do is read and process the data file, as described next, without worrying about how realistic the data is.

The simplest way for the program to proceed is to initialize the structure contents to zeros, read the file data into temporary variables, and then add them to the contents of the corresponding structure. After the program has finished reading the file, it should then calculate the batting average for each player and store it in the corresponding structure member. The batting average is calculated by dividing the cumulative number of hits for a player by the cumulative number of at-bats; it should be a floating-point
calculation. The program should then display the cumulative data for each player along with a line showing the combined statistics for the entire team.

程序实现功能:

  1. 从一个文件中读取一个类球队的信息:球员号,名,姓,上场次数,击中次数,走垒数,打点,安打率(击中数/上场次数)。
  2. 文件中信息可能是多场比赛数据,因此一个球员可能有多行数据。因此需要将每个球员的数据累加到一起。
  3. 声明一个结构体数组来保存信息,用球员号码作为数组索引,号码为 0~18之间。
#include
#include
#include
#define LEN 10
#define SIZE 41
#define NUM 19
typedef struct
{
  int num;
  char fname[LEN];
  char lname[LEN];
  int play_t;
  int hit_t;
  int walk_t;
  int rbi;
  float bat_ave;
} player;
char *s_gets(char *st, int n);
void init(player *pt, int n);
void show_data(player *pt, int n);
int main(void)
{
  char file[SIZE];
  FILE *fp;
  int flag = 0;
  player mem[NUM];
  player temp;
  printf("Please enter the filename: ");
  s_gets(file, SIZE);
  if((fp = fopen(file, "r")) == NULL)
  { 
    fprintf(stderr, "Can't open file %s.\n",file);
    exit(EXIT_FAILURE);
  }
  init(mem, NUM);
  while(fscanf(fp,"%d %s %s %d %d %d %d",
  &temp.num,temp.fname,temp.lname,&temp.play_t,&temp.hit_t,&temp.walk_t,&temp.rbi)==7)
  {
    if(temp.num = 0 && flag == 0)
    {
      flag = 1;
      mem[0].num = 0;
      strcpy(mem[0].fname, temp.fname);
      strcpy(mem[0].lname, temp.lname);
      mem[0].play_t += temp.play_t;
      mem[0].hit_t += temp.hit_t;
      mem[0].walk_t += temp.walk_t;
      mem[0].rbi += temp.rbi;
    }
    else // temp.num != 0 || flag = 1
    {
      mem[temp.num].play_t += temp.play_t;
      mem[temp.num].hit_t += temp.hit_t;
      mem[temp.num].walk_t += temp.walk_t;
      mem[temp.num].rbi += temp.rbi;
    }
  }
  if(feof == 0)
  fprintf(stderr,"Read file %s error.\n",file);
  if(fclose(fp))
  fprintf(stderr,"Can't close file %s.\n",file);
  show_data(mem,NUM); 
  return 0;
}
char *s_gets(char *st, int n)
{
 char *ret_val, *find;
 ret_val = fgets(st, n, stdin);
 if(ret_val)
 {
   find = strchr(st, '\n');
   if(find)
   *find = '\0';
   else
   while(getchar() != '\n')
   continue;
 }
 return ret_val;
}
void init(player *pt, int n)
{
  for(int i = 0; i < n; i++)
  {
    pt[i].num = 0;
    strcpy(pt[i].fname, "");//在非初始化时给数组赋值
    strcpy(pt[i].lname,"");
    pt[i].play_t = 0;
    pt[i].hit_t = 0;
    pt[i].walk_t = 0;
    pt[i].rbi = 0;
    pt[i].bat_ave = 0;
  } 
}
void show_data(player *pt, int n)
{
  for(int i = 0; i < n; i++)
  printf("%d %s %s %d %d %d %d %.2f\n",pt[i].num, pt[i].fname, pt[i].lname,
  pt[i].play_t, pt[i].hit_t,pt[i].walk_t,pt[i].rbi,(float)pt[i].hit_t/(float)pt[i].play_t); 
}

7. Modify Listing 14.14 so that as each record is read from the file and shown to you, you are given the chance to delete the record or to modify its contents.

If you delete the record, use the vacated array position for the next record to be read. To allow changing the existing contents, you’ll need to use the “r+b” mode instead of the “a+b” mode, and you’ll have to pay more attention to positioning the file pointer so that appended records don’t overwrite existing records. It’s simplest to make all changes in the data stored in program memory and then write the final set of information to the file. One approach to keeping track is to add a member to the book structure that indicates whether it is to be deleted.

#include
#include
#include
#include
#define LEN 40
#define MAXTITL 40
#define MAXAUTL 40
#define MAXBKS 100
struct book
{
  char title[MAXTITL];
  char author[MAXAUTL];
  float value;
};
char *s_gets(char *st, int n);
float input_f(int min);
void eatline(void);
int getlet(const char *s);
void update(struct book *pb);
int getbook(struct book *pb, int n);
void show_list(struct book *pb, int n, char *s);
int main(void)
{
  struct book library[MAXBKS];
  char filename[LEN];
  int count = 0;
  int deleted = 0;
  int filecount;
  int size = sizeof(struct book);
  FILE *fp;
  printf("Please enter the filename: ");
  s_gets(filename, LEN);
  if((fp = fopen(filename, "r")) == NULL)
  {
    fprintf(stderr,"Can't open file %s.\n",filename);
    exit(EXIT_FAILURE);
  }
  while(count < MAXBKS && fread(&library[count],size,1,fp) == 1)
  {
    if(count == 0)
    printf("Current contents of %s:\n",filename);
    printf("%s by %s: $%.2f\n",library[count].title,library[count].author,library[count].value);
    printf("Do you wish to change or delete this entry? ");
    if(getlet("yn") == 'y')
    {
      printf("Enter c to change, d to delete entry: ");
      if(getlet("cd") == 'd')
      {
        deleted++;
	    puts("Entry hasn't been stored.");
      }
      else
      {
       update(&library[count]);
       count++;
      }
    }
    else
    count++;
   }
  if(fclose(fp))
  fprintf(stderr, "Can't close file %s.\n",filename);
  if(count == MAXBKS)
  {
   printf("The file %s is full.\n",filename);
   exit(EXIT_FAILURE);
  }
  printf("%d books deleted.\n",deleted);
  filecount = getbook(library , count);
  if(filecount > 0)
  show_list(library, filecount, filename);
  puts("Done.");
  return 0;
}
void eatline(void)
{
  while(getchar() != '\n')
  continue;
}
float input_f(int min)
{
  float n;
  int status;
  int ok = 1;
  while(ok)
  {
    status = scanf("%f", &n);
    if(status != 1 || getchar() != '\n' || n < min)
    {
      printf("Enter again: ");
      eatline();
      continue;
    }
    else
    return n;
  }
}
char *s_gets(char *st, int n)
{
  char *ret_val, *find;
  ret_val = fgets(st, n, stdin);
  if(ret_val)
  {
    find = strchr(st, '\n');
    if(find)
    *find = '\0';
    else
   eatline();
  }
 return ret_val;
}
int getlet(const char *s)
{
  char c;
  int ok = 1;
  while(ok)
  {
   c = getchar();
   if(getchar() != '\n' || strchr(s, c) == NULL)
   {
    printf("Enter again: ");
    eatline();
    continue;
   }
   return c;
 }
}
void update(struct book *pb)
{
  struct book copy;
  char c;
  copy = *pb;
  puts("Enter the letter that indicates your choice:");
  puts("t) modify title		a)modify author");
  puts("v) modify value		s)quit, saving changes");
  puts("q) quit, ignore changes");
  while((c = getlet("tavsq")) != 's' && c != 'q')
  {
    switch(c)
    {
      case 't': puts("Enter new title:");
      		s_gets(copy.title, MAXTITL);
		break;
      case 'a': puts("Enter new author:");
      		s_gets(copy.author,MAXAUTL);
		break;
      case 'v': puts("Enter new value:");
      		copy.value = input_f(0);
		break;
    }
  puts("t) modify title		a)modify author");
  puts("v) modify value		s)quit, saving changes");
  puts("q) quit, ignore changes");
 }
 if(c == 's')
 *pb = copy;
}
int getbook(struct book *pb, int count)
{
  puts("Add new book title.");
  puts("Press [enter] at the start of a line to stop.");
  while(count < MAXBKS && s_gets(pb[count].title, MAXTITL) != NULL
  &&pb[count].title[0]!='\0')
  {
    puts("Now enter the author.");
    s_gets(pb[count].author,MAXAUTL);
    puts("Now enter the value.");
    pb[count++].value = input_f(0);
    if(count < MAXBKS)
    puts("Enter the next title.");
  }
  return count;
}
void show_list(struct book *pb, int n, char *file)
{
  int index;
  FILE *fp;
  if((fp = fopen(file, "w")) == NULL)
  {
    fprintf(stderr,"Can't open file %s.\n",file);
    exit(EXIT_FAILURE);
  }
  puts("Here is the list of your books.");
  for(index = 0; index < n; index++)
  {
    printf("%s by %s:$%.2f\n",pb[index].title,pb[index].author,pb[index].value);
    fwrite(&(pb[index]), sizeof(struct book),1,fp);
  }
  if(fclose(fp))
  fprintf(stderr,"Can't close file %s.\n",file);
}

8. The Colossus Airlines fleet consists of one plane with a seating capacity of 12. It makes one flight daily. Write a seating reservation program with the following features:

a. The program uses an array of 12 structures. Each structure should hold a seat identification number, a marker that indicates whether the seat is assigned, the last name of the seat holder, and the first name of the seat holder.
b. The program displays the following menu:
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. The program successfully executes the promises of its menu. Choices d) and e) require additional input, and each should enable the user to abort an entry.
d. After executing a particular function, the program shows the menu again, except for choice f).
e. Data is saved in a file between runs. When the program is restarted, it first loads in the data, if any, from the file

程序实现功能:

  1. 程序一开始执行打开文件 plane_seat.dat,如果不存在该文件,则初始化一个结构体数组。
  2. 出现菜单,选择需要的功能,只要不选择退出,循环出现菜单共选择:
    a. 列出空座位的个数
    b. 列出空座位号码
    c. 列出所有座位信息
    d. 选座位
    e. 删掉已经预定的座位
    f. 退出
  3. 选项d 和 e 需要在选择后出现提示是否保存选择,可以放弃更改
  4. 将最终结构体数组的结果写入到文件中保存,下次打开程序时自动打开该文件,并将读取信息到结构体数组中。
#include
#include
#include
#include
#define LEN 20
#define SIZE 40
#define NUM 12
typedef struct 
{
  int num;
  int selected;
  char lname[LEN];
  char fname[LEN];
} seat;
char *s_gets(char *st, int n);
void eatline(void);
int input(int min, int max);
char getlet(char *s);
void init(seat *ps, int n);
void menu(void);
char get_choice(char *s);
void choice(char c, seat *ps);
void choice_a(seat *ps, int n);
int choice_b(seat *ps, int n);
void choice_c(seat *ps, int n);
void choice_d(seat *ps, int n);
void choice_e(seat *ps, int n);
int main(void)
{
  FILE *fp;
  char c;
  int size = sizeof(seat);
  seat plane_seat[NUM];
  if((fp = fopen("plane_seat.dat", "rb")) == NULL)
  {
   init(plane_seat, NUM);
  }
  else
  {
   for(int i = 0; i < NUM; i++)
     fread(&plane_seat[i],size, 1, fp);
  fclose(fp);
  }
  menu();
  while((c = get_choice("abcdef")) != 'f')
  {
    choice(c, plane_seat);
    menu();
    puts("Enter the next choice:");
  }
  if((fp = fopen("plane_seat.dat","wb")) == NULL)
  {
    fprintf(stderr,"Can't open file %s.\n","plane_seat.dat");
    exit(EXIT_FAILURE);
  }
  for(int i = 0; i < NUM; i++)
    fwrite(&plane_seat[i],size, 1, fp);
  fclose(fp);
  puts("Bye."); 
  return 0;
}
void init(seat *ps, int n)
{
  for(int i = 0; i < n; i++)
  {
    ps[i].num = i+1;
    ps[i].selected = 0;
    strcpy(ps[i].lname,"");
    strcpy(ps[i].fname,"");
  }
}
void menu(void)
{
  puts("Enter your choice:");
  puts("a) show number of empty seat");
  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");
}
void eatline(void)
{
  while(getchar() != '\n')
  continue;
}
char *s_gets(char *st, int n)
{
  char *ret_val, *find;
  ret_val = fgets(st, n, stdin);
  if(ret_val)
  {
    find = strchr(st, '\n');
    if(find)
    *find = '\0';
    else
    eatline();
  }
  return ret_val;
}
int input(int min, int max)
{
  int n, status;
  int ok = 1;
  while(ok)
  {
    status = scanf("%d", &n);
    if(status != 1 || getchar() != '\n' || n < min || n > max)
    {
      printf("Enter again (between %d to %d): ",min, max);
      eatline();
      continue;
    }
    else
    return n;
  }
}
char getlet(char *s)
{
  char c;
  int ok = 1;
  while(ok)
  {
    c = getchar();
    c = tolower(c);
    if(strchr(s, c) != NULL && getchar() == '\n')
    return c;
    else
    {
     printf("Enter again (y/n):\n");
     eatline();
     continue;
    }
  }
}
char get_choice(char *s)
{
  char c;
  int ok = 1;
  c = getchar();
  c = tolower(c);
  while(ok)
  {
   if(strchr(s,c) != NULL && getchar() != '\n')
   {
     printf("Enter again: ");
     eatline();
     continue;
   }
   else
   return c;
  }
}
void choice(char c, seat *plane_seat)
{
  switch(c)
  {
    case 'a': choice_a(plane_seat, NUM); break;
    case 'b': choice_b(plane_seat, NUM); break;
    case 'c': choice_c(plane_seat, NUM); break;
    case 'd': choice_d(plane_seat, NUM); break;
    case 'e': choice_e(plane_seat, NUM); break;
  }
}
void choice_a(seat *ps, int n)
{
  int emp = 0;
  for(int i = 0; i < n; i++)
    if(ps[i].selected == 0)
    emp++;
  printf("The number of empty seats : %d.\n",emp);
}
int choice_b(seat *ps, int n)
{
  int ct = 0;
  printf("The list of empty seats: ");
  for(int i = 0; i < n; i++)
   if(ps[i].selected == 0)
   {
    printf("%d ",ps[i].num);
    ct++;
   }
   printf("\n");
   return ct;
}
void choice_c(seat *ps, int n)
{
  puts("Here is the list of seats.");
  puts("1. identical number 2. status  3. last name  4. first name.");
  puts("For status: 0 means empty, 1 means assigned.");
  for(int i = 0; i < n; i++)
   printf("%d %d %s %s\n",ps[i].num,ps[i].selected,ps[i].lname,ps[i].fname);
}
void choice_d(seat *ps, int n)
{
  int empty;
  seat temp;
  empty = choice_b(ps, n);
  if(empty = 0)
  printf("Sorry, no empty seats.");
  else
  {
   puts("Choose a seat form empty seats.");
   int num;
   int ok = 1;
   while(ok)
   {
    num = input(1, 12);
    if(ps[num-1].selected == 1)
    {
     printf("Sorry, number %d has been assigned, please choose another.",num);
     continue;
    }
    else
    ok = 0;
   }
   temp.num = num;
   temp.selected = 1;
   char lname[LEN];
   char fname[LEN];
   printf("Enter your last name: ");
   strcpy(temp.lname ,  s_gets(lname, LEN));
   printf("Enter your first name: ");
   strcpy(temp.fname , s_gets(fname, LEN));
   printf("Do you wish to save the change?\n");
   char c = getlet("yn");
   if(c == 'y')
   {
     ps[num-1] = temp;
     printf("numner %d is ordered.\n",num);
   }
  }
}
void choice_e(seat *ps, int n)
{
 char lname[LEN];
 char fname[LEN];
 int assigned[NUM];
 seat temp;
 int j = 0;
 int ct = 0;
 printf("Enter your last name: ");
 s_gets(lname, LEN);
 printf("Enter your first name: ");
 s_gets(fname, LEN);
 for(int i = 0; i < n; i++)
 {
   if(ps[i].selected == 1)
   {
     if(strcmp(ps[i].lname, lname)==0 && strcmp(ps[i].fname,fname)==0)
       {
         assigned[j++] = ps[i].num;
	 ct++;
       }
   }
 }
 if(ct == 0)
 puts("You haven't order any seats.");
 else
 {
   int delete;
   int ok = 1;
   int flag = 0;
   puts("Here is the list of your assigned seats:");
   for(int i = 0; i < ct; i++)
   printf("%d ",assigned[i]);
   printf("\n");
   puts("Enter the numner you want to deleted:");
   while(ok)
   {
    delete = input(1, 12);
    for(int i = 0; i < ct; i++)
    {
      if(delete == assigned[i])
         flag = 1;     
    }
    if(flag == 0)
    {
     printf("This number is not you have ordered, enter again:\n");
     continue;
    }
    else if(flag == 1) 
    {
      temp.num = delete;
      temp.selected = 0;
      strcpy(temp.lname,"");
      strcpy(temp.fname,"");
      ok = 0;
    }
   }
   printf("Do you wish to save the change?\n");
   char c = getlet("yn");
   if(c == 'y')
   {
     ps[delete-1] = temp;
     printf("Number %d has been deleted.\n",delete);
   }
 }
}

9. Colossus Airlines (from exercise 8) acquires a second plane (same capacity) and expands its service to four flights daily (Flights 102, 311, 444, and 519).

Expand the program to handle four flights. Have a top-level menu that offers a choice of flights and the option to quit. Selecting a particular flight should then bring up a menu similar to that of
exercise 8. However, one new item should be added: confirming a seat assignment. Also, the quit choice should be replaced with the choice of exiting to the top-level menu. Each display should indicate which flight is currently being handled. Also, the seat assignment display should indicate the confirmation status.

#include
#include
#include
#include
#define LEN 20
#define NUM 12
#define FLIGHTS 4
typedef struct
{
   int num;
   int selected;
   char lname[LEN];
   char fname[LEN];
} seat;
typedef struct
{
  int flight;
  seat mess[NUM];
  int status;
} plane;
char *s_gets(char *st, int n);
void eatline(void);
int input(int min, int max);
void init(plane *ps, int n);
void top_menu(void);
char getlet(char *s);
int set_mess(char c, plane *ps);
void sec_menu(void);
void choice(char c, plane *ps, int n);
void reset_flight(plane *ps);
void choice_a(plane *ps, int n);
int choice_b(plane *ps, int n);
void choice_c(plane *ps, int n);
void choice_d(plane *ps, int n);
void choice_e(plane *ps, int n);
int main(void)
{
  FILE *fp;
  plane airline[FLIGHTS];
  int size = sizeof(plane);
  char c1, c2;
  int ok = 1;
  int good = 1;
  int flight_num;
  if((fp = fopen("airline.dat", "rb")) == NULL)
  init(airline, FLIGHTS);
  else
  {
    for(int i = 0; i < FLIGHTS; i++)
    fread(&airline[i], size, 1, fp);
    fclose(fp);
  }
  top_menu();
  while(ok)
  {
   c1 = getlet("abcde");
   if(c1 != 'e')
   {
     flight_num = set_mess(c1, airline);
     sec_menu();
     while(good)
     {
       c2 = getlet("abcdef");
       if(c2 != 'f')
        {
	 choice(c2, airline, flight_num);
	 sec_menu();
        }
       else
       good = 0;
     }
    top_menu(); 
   }
   else
   ok = 0;
  }
 reset_flight(airline);
 if((fp = fopen("airline.dat","wb")) == NULL)
 {
   fprintf(stderr,"Can't open file %s.\n","airline.dat");
   exit(EXIT_FAILURE);
 }
  for(int i = 0; i < FLIGHTS; i++)
  fwrite(&airline[i], size, 1, fp);
  fclose(fp);
  puts("Bye!");
  return 0;
}
void reset_flight(plane *ps)
{
  for(int i = 0; i < FLIGHTS; i++)
  ps[i].status = 0;
}
void init(plane *ps, int n)
{
  ps[0].flight = 101;
  ps[1].flight = 311;
  ps[2].flight = 444;
  ps[3].flight = 519;
  for(int i = 0; i < n; i++)
  {
    ps[i].status = 0;
    for(int j = 0; j < NUM; j++)
    {
      ps[i].mess[j].num = j+1;
      ps[i].mess[j].selected = 0;
      strcpy(ps[i].mess[j].lname,"");
      strcpy(ps[i].mess[j].fname,"");
    }
  }
}
int input(int min, int max)
{
  int ok = 1;
  int n, status;
  while(ok)
  {
   status = scanf("%d",&n);
   if(status != 1 || getchar() != '\n' || nmax)
   {
    printf("Enter again (between %d to %d):\n",min,max);
    eatline();
    continue;
   }
   else
   return n;
  }
}
char *s_gets(char *st, int n)
{
  char *ret_val, *find;
  ret_val = fgets(st, n, stdin);
  if(ret_val)
  {
    find = strchr(st, '\n');
    if(find)
    *find = '\0';
    else
    eatline();
  }
  return ret_val;
}
void top_menu(void)
{
  puts("Choose your flight:");
  puts("a) 101	b) 311");
  puts("c) 444	d) 519");
  puts("e) quit");
}
void eatline(void)
{
  while(getchar() != '\n')
  continue;
}
int set_mess(char c, plane *ps)
{
  int num;
  switch(c)
  {
    case 'a': num = 0;
    	      ps[0].status = 1;
	      puts("flight 101 is being handled.");
	      break;
    case 'b': num = 1;
    	      ps[1].status = 1; 
	      puts("flight 311 is being handled.");
	      break;
    case 'c': num = 2;
    	      ps[2].status = 1;
              puts("flight 444 is being handled.");
	      break;
    case 'd': num = 3;
    	      ps[3].status = 1;
	      puts("flight 519 is being handled.");
	      break;
  }
  return num;
}
char getlet(char *s)
{
  char c;
  int ok = 1;
  while(ok)
  {
    c = getchar();
    c = tolower(c);
    if(getchar() != '\n' || strchr(s,c)==NULL)
    {
      printf("Enter again: ");
      eatline();
      continue;
    }
    else
    return c;
  }
}
void sec_menu(void)
{
  puts("Enter your choice:");
  puts("a) show number of empty seats");
  puts("b) show list of list 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");
}
void choice(char c, plane *ps, int n)
{
  switch (c)
  {
    case 'a': choice_a(ps,n); break;
    case 'b': choice_b(ps,n); break;
    case 'c': choice_c(ps,n); break;
    case 'd': choice_d(ps,n); break;
    case 'e': choice_e(ps,n); break;
  }
}
void choice_a(plane *ps, int n)
{
  int ct = 0;
  for(int i = 0; i < NUM; i++)
    if(ps[n].mess[i].selected == 0)
    ct++;
    printf("flight %d has %d empty seats.\n",ps[n].flight, ct);
}
int choice_b(plane *ps, int n)
{
  int num;
  int ct = 0;
  printf("Here is the list of the empty seats of flight %d.\n",ps[n].flight);
  for(int i = 0; i < NUM; i++)
   if(ps[n].mess[i].selected == 0)
   {
     ct++;
     printf("%d ",ps[n].mess[i].num);
   }
  if(ct == 0)
  printf("Flight %d has no empty seats.\n", ps[n].flight);
  else
  printf("\n");
  return ct;
}
void choice_c(plane *ps, int n)
{
  printf("Here is the list of seats about flight %d.\n",ps[n].flight);
  puts("1. identical number 2. status 3. last name 4. first name");
  puts("For status: 1 means assigned, 0 means empty");
  for(int i = 0; i < NUM; i++)
  printf("%d %d %s %s\n",ps[n].mess[i].num,ps[n].mess[i].selected,ps[n].mess[i].lname,ps[n].mess[i].fname);
}
void choice_d(plane *ps, int n)
{
  char lname[LEN];
  char fname[LEN];
  int ct = choice_b(ps,n);
  int num;
  int ok = 1;
  if(ct == 0)
  printf("Sorry, flight %d has no empty seats to orded, choose another flight.\n",ps[n].flight);
  else
  {
    printf("Please select a seat from the empty seat numbers listed above.\n");
    while(ok)
    {
     num = input(1 , NUM);
     if(ps[n].mess[num-1].selected == 1)
     {
      printf("number %d has been ordered, enter again:\n",num);
      continue;
     }
     else
     ok = 0;
    }
    puts("Please enter your last name:");
    s_gets(lname,LEN);
    puts("Please enter your first name:");
    s_gets(fname,LEN);
    puts("Do you wish to save the change ? ");
    char c = getlet("yn");
    if(c == 'y')
   {
    strcpy(ps[n].mess[num-1].lname,lname);
    strcpy(ps[n].mess[num-1].fname,fname);
    ps[n].mess[num-1].selected = 1;
   }
  }
}
void choice_e(plane *ps, int n)
{
  char lname[LEN];
  char fname[LEN];
  char c;
  int flag = 0;
  int ct = 0;
  int delete;
  char assigned[NUM];
  int j;
  int ok;
  printf("Please enter your last name:\n");
  s_gets(lname, LEN);
  printf("Please enter your first name:\n");
  s_gets(fname, LEN);
  puts("Here is the list of seats you have ordered:");
  for(int i = 0, j = 0; i < NUM; i++)
  {
   if(strcmp(lname,ps[n].mess[i].lname)==0
   &&strcmp(fname,ps[n].mess[i].fname)==0)
   {
     flag = 1;
     ct++;
     assigned[j++] = ps[n].mess[i].num;
     printf("%d ",ps[n].mess[i].num);
   }
  }
  if(flag == 0)
  puts("Sorry, you haven't ordered any seat.");
  else
  {
   ok = 1;
   flag = 0;
   puts("Input the number you want to delete:");
   while(ok)
   {
   delete = input(1 , NUM);
   for(int i = 0; i < ct,flag == 0; i++)
     if(delete == assigned[i])
        flag = 1;
   if(flag == 0)
   {
     printf("Select a number from numbers you have ordered, enter again:\n");
     continue;
   }
   else
   ok = 0;
   }
   puts("Do you want to save the chagne ? ");
   c = getlet("yn");
   if(c == 'y')
   {
     ps[n].mess[delete-1].selected = 0;
     strcpy(ps[n].mess[delete-1].lname,"");
     strcpy(ps[n].mess[delete-1].fname,"");
   }
  }
}

10. Write a program that implements a menu by using an array of pointers to functions. For instance, choosing a from the menu would activate the function pointed to by the first element of the array.

#include
#include//编译要加上 -lm ,m指 math.h gcc -g 10.c -lm -o 10.o
#define NUM 4
double twice(double x);
double half(double x);
double thrice(double x);
void menu(void);
double input_f(void);
int input_i(int min, int max);
void eatline(void);
int main(void)
{
  double (*pt[NUM])(double) = {twice, half, thrice, sqrt};
  double val;
  double ans;
  int sel;
  char c;
  printf("Enter a number (negative to quit): ");
  while((val = input_f()) >= 0)
  {
    menu();
    sel = input_i(0, NUM);
    while(sel != 4)
    {
      ans = (*pt[sel])(val);
      printf("Answer = %f\n",ans);
      ans = pt[sel](val);//another expression
      printf("to repeat, answer = %f\n",ans);
      menu();
      sel = input_i(0 , NUM);
    }
    printf("Enter next number (negative to quit):\n");
  }
  puts("Bye");
  return 0;
}
void eatline(void)
{
  while(getchar() != '\n')
  continue;
}
double input_f(void)
{
  int status;
  double n;
  int ok = 1;
  while(ok)
  {
    status = scanf("%lf",&n);
    if(status != 1 || getchar() != '\n')
    {
      printf("Enter a number, input again:\n");
      eatline();
      continue;
    }
  else
  return n;
  }
}
void menu(void)
{
  puts("Enter one of the following choices:");
  puts("0) double the value  1) halve the value");
  puts("2) triple the value  3) squareroot the value");
  puts("4) quit");
}
int input_i(int min, int max)
{
  int status, n;
  int ok = 1;
  while(ok)
  {
    status = scanf("%d", &n);
    if(status != 1 || getchar() != '\n' || n < min || n > max)
    {
      printf("Enter again (between %d to %d):\n",min,max);
      eatline();
      continue;
    }
    else
    return n;
  }
}
double twice(double x) {return 2.0 * x;}
double half(double x) {return x / 2.0;}
double thrice(double x) {return 3.0 * x;}

11. Write a function called transform() that takes four arguments: the name of a source array containing type double data, the name of a target array of type double, an int representing the number of array elements, and the name of a function (or, equivalently, a pointer to a function). The transform() function should apply the indicated function to each element in the source array, placing the return value in the target array.

For example, the call

transform(source, target, 100, sin);

would set target[0] to sin(source[0]), and so on, for 100 elements. Test the function in a program that calls transform() four times, using two functions from the math.h library and two suitable functions of your own devising as arguments to successive calls of the transform() function.

#include
#include
#include
#include
#include
#include
void transform(double *source, double *target, unsigned int num, double (*fp)(double));
unsigned int input_i(unsigned int min , unsigned int max);
void eatline(void);
void menu(void);
char getlet(char *st);
double input_f(void);
void choice(char c, double *s, double *t, int n);
double twice(double x);
double square(double x);
int main(void)
{
  unsigned int len;
  char c;
  puts("Enter the number of elements to calculate:");
  len = input_i(1 , UINT_MAX);
  double *source = malloc(len * sizeof(double));
  double *target = malloc(len * sizeof(double));
  double (*fp)(double);
  puts("Enter number of data:");
  for(int i = 0; i < len; i++)
    source[i] = input_f();
  menu();
  c = getlet("abcde");
  while(c != 'e')
  {
    choice(c , source, target, len);
    puts("Do you want to replace the data ? ");
    c = getlet("yn");
    if(c == 'y')
    {
      free(source);
      free(target);
      puts("Enter number of data:");
      len = input_i(1 , UINT_MAX);
      double *source = malloc(len * sizeof(double));
      double *target = malloc(len * sizeof(double));
      puts("Enter number of data:");
      for(int i = 0; i < len; i++)
      source[i] = input_f();
    }
    menu();
    c = getlet("abcdef");
  }
  free(source);
  free(target);
  puts("Bye!");
  return 0;
}
void eatline(void)
{
  while(getchar() != '\n')
  continue;
}
unsigned int input_i(unsigned int min, unsigned int max)
{
  unsigned n;
  int status;
  int ok = 1;
  while(ok)
  {
  status = scanf("%d",&n);
  if(status != 1 || getchar() != '\n' || n < min || n > max)
  {
    printf("Enter a positive integet between %d to %d.\n",min,max);
    eatline();
    continue;
  }
  else
  return n;
  }
}
double input_f(void)
{
  int status;
  int ok = 1;
  double n;
  while(ok)
  {
    status = scanf("%lf",&n);
    if(status != 1 || getchar() != '\n')
    {
      puts("Enter again:");
      eatline();
      continue;
    }
    else
    return n;
  }
}
void menu(void)
{
  puts("Enter one of the following choice:");
  puts("a) calculate the square root");
  puts("b) calculate the natural logarithm of the cardinal number e");
  puts("c) double the value");
  puts("d) square the value");
  puts("e) quit");
}
char getlet(char *s)
{
  char c;
  int ok = 1;
  while(ok)
 {
  c = getchar();
  c = tolower(c);
  if(getchar() != '\n' || strchr(s,c) == NULL)
  {
    puts("Enter again:");
    eatline();
    continue;
  }
  else
  return c;
 }
}
void choice(char c, double *s, double *t, int n)
{
  double (*fp)(double);
  switch(c)
  {
   case 'a': fp = sqrt;
             puts("Results of the calculation of the square root of these numbers:");
	     break;
   case 'b': fp = log;
   	     puts("Results of the calculation of log of these numbers:");
	     break;
   case 'c': fp = twice; 
   	     puts("Results of the calculation of twice of these numbers:");
	     break;
   case 'd': fp = square;
   	     puts("Results of the calculation of square of these numbers:");
	     break;
  }
  transform(s, t, n, fp);
}
void transform(double *s, double *t, unsigned int n, double (*fp)(double))
{
  for(int i = 0; i < n; i++)
  {
    t[i] = (*fp)(s[i]);
    printf("%.2f ",t[i]);
    if((i + 1) % 5 == 0)
    printf("\n");
  }
  printf("\n");
}
double twice (double x) 
{
  return (2.0 * x);
}
double square (double x)
{
  return (x * x);
}

你可能感兴趣的:(C,Primer,Plus)