When processing large amounts of data, it is often easier to group information together,
instead of dealing with lots of individual variables. For example, to keep track of
a customer's name, account balance, and account number, we will sometime want to group
this information in a structure:
struct customer {
char fname[20],lname[20];
int acct_num;
float acct_balance;
};
In both C and C++, we can read and write an entire structure at once instead of reading and writing every part individually.
Note that these files are not text files. If you wrote the above structure into a file, then edited the file with vi, you would not recognize much. For example, the float in the file would be the actual bytes, not the human readable form. Since characters take one byte each, you could probably read the first and last names.
The function to write a struct in C is fwrite().
fwrite (* struct, size, count, file);
The first argument is the location of the structure to write. The second argument is
the byte size of that structure. The third argument is how many of those structures
to write. The fourth argument is the output file.
So, given this declaration,
struct account my_acct;
we could write the entire structure with this command:
fwrite (&my_acct, sizeof (struct account), 1, outfile);
Given an array of 15 of these structures,
struct account my_acct[15];
we could write all 15 elements
fwrite (my_acct, sizeof (struct account), 15, outfile);
Here is an example program to read some data from the keyboard then write the data into a file.
/********************************** C Demo of how to WRITE using fwrite. **********************************/ #include <stdio.h> #include <stdlib.h> #include <string.h> // a structure to read and write struct customer { char fname[20],lname[20]; int acct_num; float acct_balance; }; /**************************************/ void main () { FILE *outfile; struct customer input; // open Accounts file for writing outfile = fopen ("accounts.dat","w"); if (outfile == NULL) { fprintf(stderr, "\nError opening accounts.dat\n\n"); exit (1); } // instructions to user printf("Enter \"stop\" for First Name to end program."); // endlessly read from keyboard and write to file while (1) { // prompt user printf("\nFirst Name: "); scanf ("%s", input.fname); // exit if no name provided if (strcmp(input.fname, "stop") == 0) exit(1); // continue reading from keyboard printf("Last Name : "); scanf ("%s", input.lname); printf("Acct Num : "); scanf ("%d", &input.acct_num); printf("Balance : "); scanf ("%f", &input.acct_balance); // write entire structure to Accounts file fwrite (&input, sizeof(struct customer), 1, outfile); } } |
The C function to read a structure is fread(). The format is:
fread (* struct, size, count, file);
So, the arguments to fread() are the same as fwrite().
Here is C program to read the file that the above program writes. Notice that it does not use feof() to check for end-of-file. Instead it reads until fread() returns a 0, meaning zero bytes were read.
/********************************** C Demo how to READ with fread. **********************************/ #include >stdio.h> #include >stdlib.h> struct customer { char fname[20],lname[20]; int acct_num; float acct_balance; }; void main () { FILE *infile; struct customer input; /*** open the accounts file ***/ infile = fopen ("accounts.dat","r"); if (infile == NULL) { fprintf(stderr, "\nError opening accounts.dat\n\n"); exit (1); } while (fread (&input, sizeof(struct customer), 1, infile)) printf ("Name = %10s %10s Acct Num = %8d Balance = %8.2f\n", input.fname, input.lname, input.acct_num, input.acct_balance); } |
Here is those two programs run back to back.
> write_demo Enter "stop" for First Name to end program. First Name: Steve Last Name : Dannelly Acct Num : 1234 Balance : -99.99 First Name: Bob Last Name : Jones Acct Num : 321 Balance : 8888.88 First Name: Sally Last Name : Smith Acct Num : 567 Balance : 47.95 First Name: stop > read_demo Name = Steve Dannelly Acct Num = 1234 Balance = -99.99 Name = Bob Jones Acct Num = 321 Balance = 8888.88 Name = Sally Smith Acct Num = 567 Balance = 47.95
C++ has its own versions of fread and fwrite. They are the "read" and "write" methods for the ifstream and ofstream classes, respectively.
fstream account_file; account_type account; ... account_file.open (yadda yadda); ... account_file.read (reinterpret_cast <char *> (&account), sizeof(account));The write method has the same parameters.