Arrays of Structures

I l @ ve RuBoard

Arrays of Structures

Let's extend our book program to handle more books. Clearly, each book can be described by one structure variable of the book type. To describe two books, you need to use two such variables , and so on. To handle several books, you can use an array of such structures, and that is what we have created in the next program, shown in Listing 14.2. (If you're using Borland C/C++, read the box "Borland C and Floating Point.")

Structures and Memory

The manybook.c program uses an array of 100 structures. Because the array is an automatic storage class object, the information is typically placed on the stack. Such a large array requires a good- sized chunk of memory, which can cause problems. If you get a runtime error, perhaps complaining about the stack size or stack overflow, your compiler probably uses a default size for the stack that is too small for this example. To fix things, you can use the compiler options to set the stack size to 10,000 to accommodate the array of structures, or you can make the array static or external (so that it isn't placed in the stack), or you can reduce the array size to 16. Why didn't we just make the stack small to begin with? Because you should know about the potential stack size problem so that you can cope with it if you run into it on your own.

Borland C and Floating Point

Older Borland C compilers attempt to make programs more compact by using a small version of scanf() if the program doesn't use floating-point values. However, the compilers (through Borland C/C++ 3.1 for DOS, but not Borland C/C++ 4.0) are fooled if the only floating-point values are in an array of structures, as in the case for Listing 14.2. As a result, you get a message like this:

 scanf : floating point formats not linked Abnormal program termination 

One workaround is adding this code to your program:

 #include <math.h> double dummy = sin(0.0); 

This code forces the compiler to load the floating-point version of scanf() .

Listing 14.2 The manybook.c program.
 /* manybook.c -- multiple book inventory */ #include <stdio.h> #define MAXTITL   40 #define MAXAUTL   40 #define MAXBKS   100            /* maximum number of books  */ struct book {                   /* set up book template     */     char title[MAXTITL];     char author[MAXAUTL];     float value; }; int main(void) {      struct book libry[MAXBKS]; /* array of book structures */      int count = 0;      int index;      printf("Please enter the book title.\n");      printf("Press [enter] at the start of a line to stop.\n");      while (count < MAXBKS && gets(libry[count].title) != NULL                          && libry[count].title[0] != ' 
  /* manybook.c -- multiple book inventory */ #include <stdio.h> #define MAXTITL 40 #define MAXAUTL 40 #define MAXBKS 100 /* maximum number of books */ struct book { /* set up book template */ char title[MAXTITL]; char author[MAXAUTL]; float value; }; int main(void) { struct book libry[MAXBKS]; /* array of book structures */ int count = 0; int index; printf("Please enter the book title.\n"); printf("Press [enter] at the start of a line to stop.\n"); while (count < MAXBKS && gets(libry[count].title) != NULL && libry[count].title[0] != '\0') { printf("Now enter the author.\n"); gets(libry[count].author); printf("Now enter the value.\n"); scanf("%f", &libry[count++].value); while ( getchar () != '\n') continue; /* clear input line */ if (count < MAXBKS) 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", libry[index].title, libry[index].author, libry[index].value); return 0; }  
') { printf("Now enter the author.\n"); gets(libry[count].author); printf("Now enter the value.\n"); scanf("%f", &libry[count++].value); while (getchar() != '\n') continue; /* clear input line */ if (count < MAXBKS) 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", libry[index].title, libry[index].author, libry[index].value); return 0; }

Here is a sample program run:

 Please enter the book title. Press [enter] at the start of a line to stop.  My Life as a Budgie  Now enter the author.  Mack Zackles  Now enter the value.  12.95  Enter the next title.     ...more entries... Here is the list of your books: My Life as a Budgie by Mack Zackles: .95 Thought and Unthought Rethought by Kindra Schlagmeyer: .50 The Business of a Bee by Salome Deschamps: .99 The CEO Power Diet by Buster Downsize: .25 C++ Primer Plus by Stephen Prata: .95 Coping with Coping by Dr. Rubin Thonkwacker: 
  Please enter the book title. Press [enter] at the start of a line to stop.  My Life as a Budgie  Now enter the author.  Mack Zackles  Now enter the value.  12.95  Enter the next title. ...more entries... Here is the list of your books: My Life as a Budgie by Mack Zackles: $12.95 Thought and Unthought Rethought by Kindra Schlagmeyer: $43.50 The Business of a Bee by Salome Deschamps: $14.99 The CEO Power Diet by Buster Downsize: $19.25 C++ Primer Plus by Stephen Prata: $32.95 Coping with Coping by Dr. Rubin Thonkwacker: $0.00 Delicate Frivolity by Neda McFey: $29.99 Murder Wore a Bikini by Mickey Splats: $18.95 A History of Buvania, Volume 2, by Prince Nikoli Buvan: $50.00 Mastering Your Digital Watch, 2nd Edition, by Miklos Mysz: $18.95 A Foregone Confusion by Phalty Reasoner: $5.99  
.00 Delicate Frivolity by Neda McFey: .99 Murder Wore a Bikini by Mickey Splats: .95 A History of Buvania, Volume 2, by Prince Nikoli Buvan: .00 Mastering Your Digital Watch, 2nd Edition, by Miklos Mysz: .95 A Foregone Confusion by Phalty Reasoner: .99

First, we'll describe how to declare arrays of structures and how to access individual members . Then we will highlight two aspects of the program.

Declaring an Array of Structures

Declaring an array of structures is like declaring any other kind of array.

 struct book libry[MAXBKS]; 

This declares libry to be an array with MAXBKS elements. Each element of this array is a structure of book type. Thus, libry[0] is one book structure, libry[1] is a second book structure, and so on. Figure 14.2 may help you visualize this. The name libry itself is not a structure name; it is the name of the array whose elements are type struct book structures.

Figure 14.2. An array of structures.
graphics/14fig02.jpg

Identifying Members of an Array of Structures

To identify members of an array of structures, you apply the same rule used for individual structures: Follow the structure name with the dot operator and then with the member name.

 libry[0].value   /* the value associated with the first array element */ libry[4].title   /* the title associated with the fifth array element */ 

Note that the array subscript is attached to libry , not to the end of the name:

 libry.value[2]    /* WRONG */ libry[2].value    /* RIGHT */ 

The reason libry[2].value is used is that libry[2] is the structure variable name, just as libry[1] is another structure variable name.

By the way, what do you suppose the following represents?

 libry[2].title[4] 

It's the fifth character in the title (the title[4] part) of the book described by the third structure (the libry[2] part). In the example, it would be the character A . This example points out that subscripts found to the right of the dot operator apply to individual members, but subscripts to the left of the dot operator apply to arrays of structures.

Let's finish the program now.

Program Details

The main change from the first program is that we inserted a loop to read multiple entries. The loop begins with this while condition:

 while (count < MAXBKS && gets(libry[count].title) != NULL                   && libry[count].title[0] != ' 
 while (count < MAXBKS && gets(libry[count].title) != NULL && libry[count].title[0] != '\0') 
')

The expression gets(libry[count].title) reads a string for the title of a book; the expression evaluates to NULL if gets() attempts to read past the end-of-file. The expression libry[count].title[0] != '\0' tests whether the first character in the string is the null character, that is, if the string is empty. If the user presses the Enter key at the beginning of a line, the empty string is transmitted, and the loop ends. We also have a check to keep the number of books entered from exceeding the array's size limit.

Then the program has these lines:

 while (getchar() != '\n')   continue;              /* clear input line */ 

As you might recall from earlier chapters, this code overcomes the scanf() function ignoring spaces and newlines. When you respond to the request for the book's value, you type something like this:

 12.50[enter] 

This statement transmits the following sequence of characters :

 12.50\n 

The scanf() function collects the 1 , the 2 , the ., the 5 , and the , but it leaves the \n sitting there, awaiting whatever read statement comes next. If the precautionary code were missing, the next read statement, gets(libry[count].title) , would read the leftover newline character as an empty line, and the program would think you had sent a stop signal. The code we inserted will eat up characters until it finds and disposes of the newline. It doesn't do anything with the characters except remove them from the input queue. This gives gets() a fresh start.

Now let's return to exploring structures.

I l @ ve RuBoard


C++ Primer Plus
C Primer Plus (5th Edition)
ISBN: 0672326965
EAN: 2147483647
Year: 2000
Pages: 314
Authors: Stephen Prata

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net