14.9 Writing Data Randomly to a Random-Access File

Figure 14.11 writes data to the file credit.dat and uses the combination of fstream functions seekp and write to store data at exact locations in the file. Function seekp sets the put file-position pointer to a specific position in the file, then function write outputs the data. Line 6 includes the header ClientData.h defined in Fig. 14.8, so the program can use ClientData objects.


Fig. 14.11 Writing to a random-access file.

Alternate View

 1   // Fig. 14.11: Fig14_11.cpp
 2   // Writing to a random-access file.
 3   #include <iostream>
 4   #include <fstream>
 5   #include <cstdlib>
 6   #include "ClientData.h" // ClientData class definition
 7   using namespace std;
 8
 9   int main() {
10      fstream outCredit{"credit.dat", ios::in | ios::out | ios::binary};
11
12      // exit program if fstream cannot open file
13      if (!outCredit) {
14         cerr << "File could not be opened." << endl;
15         exit(EXIT_FAILURE);
16      }
17
18      cout << "Enter account number (1 to 100, 0 to end input)
? ";
19
20      int accountNumber;
21      string lastName;
22      string firstName;
23      double balance;
24
25      cin >> accountNumber; // read account number
26
27      // user enters information, which is copied into file
28      while (accountNumber > 0 && accountNumber <= 100) {
29         // user enters last name, first name and balance
30         cout << "Enter lastname, firstname and balance
? ";
31         cin >> lastName;
32         cin >> firstName;
33         cin >> balance;
34
35         // create ClientData object
36         ClientData client{accountNumber, lastName, firstName, balance};
37
38         // seek position in file of user-specified record
39         outCredit.seekp(                                         
40            (client.getAccountNumber() - 1) * sizeof(ClientData));
41
42
43         // write user-specified information in file
44         outCredit.write(                                               
45            reinterpret_cast<const char*>(&client), sizeof(ClientData));
46
47         // enable user to enter another account
48         cout << "Enter account number
? ";
49         cin >> accountNumber;
50      }
51   }

Enter account number (1 to 100, 0 to end input)
? 37
Enter lastname, firstname and balance
? Barker Doug 0.00
Enter account number
? 29
Enter lastname, firstname and balance
? Brown Nancy -24.54
Enter account number
? 96
Enter lastname, firstname and balance
? Stone Sam 34.98
Enter account number
? 88
Enter lastname, firstname and balance
? Smith Dave 258.34
Enter account number
? 33
Enter lastname, firstname and balance
? Dunn Stacey 314.33
Enter account number
? 0

14.9.1 Opening a File for Input and Output in Binary Mode

Line 10 uses the fstream object outCredit to open the existing credit.dat file. The file is opened for input and output in binary mode by combining the file-open modes ios::in, ios::out and ios::binary. Note that because we include ios::in, if the file does not exist, an error will occur and the file will not be opened. Opening the existing credit.dat file in this manner ensures that this program can manipulate the records written to the file by the program of Fig. 14.10, rather than creating the file from scratch.

14.9.2 Positioning the File-Position Pointer

Lines 39–40 position the put file-position pointer for object outCredit to the byte location calculated by


(client.getAccountNumber() - 1) * sizeof(ClientData)

Because the account number is between 1 and 100, we subtract 1 from the account number when calculating the byte location of the record. Thus, for record 1, the file-position pointer is set to byte 0—the beginning of the file. For record 2, the the file-position pointer is set to 1 * sizeof(ClientData), and so on.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset