0% found this document useful (0 votes)
47 views66 pages

File Processing: 2008 Pearson Education, Inc. All Rights Reserved

The document discusses file processing in C++. It covers objectives like creating, reading, writing and updating sequential and random access files. It explains how files are viewed as sequences of bytes in C++ and communication with files is done through stream objects. It discusses creating and opening files for input/output using ifstream, ofstream and fstream classes. It also covers reading and writing data to sequential files, seeking to different positions in a file, and closing files.

Uploaded by

YSheng Chan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
47 views66 pages

File Processing: 2008 Pearson Education, Inc. All Rights Reserved

The document discusses file processing in C++. It covers objectives like creating, reading, writing and updating sequential and random access files. It explains how files are viewed as sequences of bytes in C++ and communication with files is done through stream objects. It discusses creating and opening files for input/output using ifstream, ofstream and fstream classes. It also covers reading and writing data to sequential files, seeking to different positions in a file, and closing files.

Uploaded by

YSheng Chan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 66

1

11
File Processing
2008 Pearson Education, Inc. All rights reserved.

OBJECTIVES
In this chapter youll learn: To create, read, write and update files. Sequential file processing. Random-access file processing. To use high-performance unformatted I/O operations. The differences between formatted-data and raw-data file processing. To build a transaction-processing program using random-access file processing.
2008 Pearson Education, Inc. All rights reserved.

17.1 17.2 17.3 17.4 17.5 17.6 17.7 17.8 17.9 17.10 17.11

Introduction The Data Hierarchy Files and Streams Creating a Sequential File Reading Data from a Sequential File Updating Sequential Files Random-Access Files Creating a Random-Access File Writing Data Randomly to a Random-Access File Reading from a Random-Access File Sequentially Case Study: A Transaction-Processing Program

2008 Pearson Education, Inc. All rights reserved.

17.1 Introduction
Files
Used for data persistence
Permanent retention of large amounts of data

Stored on secondary storage devices


Magnetic disks Optical disks Tapes

2008 Pearson Education, Inc. All rights reserved.

17.3 Files and Streams


Files
Viewed by C++ as a sequence of bytes Ends either with an end-of-file marker or at a systemrecorded byte number Communication between a program and a file is performed through stream objects
<fstream> header file Stream class templates basic_ifstream for file input basic_ofstream for file output basic_fstream for file input and output Files are opened by creating objects of stream template specializations

2008 Pearson Education, Inc. All rights reserved.

Fig. 17.2 | C++s view of a file of n bytes.

2008 Pearson Education, Inc. All rights reserved.

Fig. 17.3 | Portion of stream I/O template hierarchy.

2008 Pearson Education, Inc. All rights reserved.

17.4 Creating a Sequential File


File structure
The programmer must structure files
C++ does not impose structures on files

2008 Pearson Education, Inc. All rights reserved.

17.4 Creating a Sequential File (Cont.)


Creating an ofstream object
Opens a file for output
Constructor takes two arguments
A filename If the file doe not exist, it is first created A file-open mode ios::out the default mode Overwrites preexisting data in the file ios::app Appends data to the end of the file

Can also use member function open on existing object


Takes same arguments as the constructor
2008 Pearson Education, Inc. All rights reserved.

10

17.4 Creating a Sequential File (Cont.)


Using an ofstream object
Writing to the file
Use the stream insertion operator

Member function close


Releases the file resource Implicitly performed by ofstreams destructor

ios operators (usable with ofstream)


Operator member function operator!
Returns true if either the failbit or badbit is set

Operator member function operator void *


Converts the stream to a pointer The null pointer if either the failbit or badbit is set
2008 Pearson Education, Inc. All rights reserved.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29

// Fig. 17.4: Fig17_04.cpp // Create a sequential file. #include <iostream> using using using using using std::cerr; std::cin; std::cout; std::endl; std::ios;

11

Outline

Fig17_04.cpp

(1 of 2)

#include <fstream> // file stream using std::ofstream; // output file stream #include <cstdlib> using std::exit; // exit function prototype

Open file client.dat for output


int main() { // ofstream constructor opens file ofstream outClientFile( "clients.dat", ios::out ); // exit program if unable to create file if ( !outClientFile ) // overloaded ! operator { cerr << "File could not be opened" << endl; exit( 1 ); } // end if cout << "Enter the account, name, and balance." << endl << "Enter end-of-file to end input.\n? ";

Overloaded operator! will return true if the file did not open successfully

2008 Pearson Education, Inc. All rights reserved.

30 31 32 33 34 35 36 37 38 39 40 41 42 return 0; // ofstream destructor closes file 43 } // end main Enter Enter ? 100 ? 200 ? 300 ? 400 ? 500 ? ^Z the account, name, and balance. end-of-file to end input. Jones 24.98 Doe 345.67 White 0.00 Stone -42.16 Rich 224.62 // read account, name and balance from cin, then place in file while ( cin >> account >> name >> balance ) { cout << "? "; } // end while int account; char name[ 30 ]; double balance;

12

Outline
Overloaded operator void * will return the null pointer 0 Fig17_04.cpp (false) when the user enters the end-of-file indicator (2 of 2) Write data to client.dat using the stream insertion operator ofstream destructor implicitly closes the file

outClientFile << account << ' ' << name << ' ' << balance << endl;

2008 Pearson Education, Inc. All rights reserved.

13

Common Programming Error 17.1


Use caution when opening an existing file for output (ios::out), especially when you want to preserve the files contents, which will be discarded without warning.

2008 Pearson Education, Inc. All rights reserved.

14

Mode
ios::app ios::ate ios::in ios::out ios::trunc ios::binary

Description
Append all output to the end of the file. Open a file for output and move to the end of the file (normally used to append data to a file). Data can be written anywhere in the file. Open a file for input. Open a file for output. Discard the files contents if they exist (this also is the default action for ios::out). Open a file for binary (i.e., nontext) input or output.

Fig. 17.5 | File open modes.

2008 Pearson Education, Inc. All rights reserved.

15

Common Programming Error 17.2


Not opening a file before attempting to reference it in a program will result in an error.

2008 Pearson Education, Inc. All rights reserved.

16

Computer system
UNIX/Linux/Mac OS X Microsoft Windows VAX (VMS)

Keyboard combination
<ctrl-d> (on a line by itself) <ctrl-z> (sometimes followed by pressing Enter) <ctrl-z>

Fig. 17.6 | End-of-file key combinations for various popular computer systems.

2008 Pearson Education, Inc. All rights reserved.

17

Performance Tip 17.1


Closing files explicitly when the program no longer needs to reference them can reduce resource usage (especially if the program continues execution after closing the files).

2008 Pearson Education, Inc. All rights reserved.

18

17.5 Reading Data from a Sequential File


Creating an ifstream object
Opens a file for input
Constructor takes two arguments
A filename A file-open mode ios::in the default mode Can only read from the file

Can also use member function open on an existing object


Takes same arguments as the constructor

2008 Pearson Education, Inc. All rights reserved.

19

Good Programming Practice 17.1


Open a file for input only (using ios::in) if the files contents should not be modified. This prevents unintentional modification of the files contents and is an example of the principle of least privilege.

2008 Pearson Education, Inc. All rights reserved.

17.5 Reading Data from a Sequential File (Cont.)


File-position pointer
The byte number of the next byte to be read or written Member functions seekg and seekp (of istream and ostream, respectively)
Repositions the file-position pointer to the specified location Takes desired offset argument as a long A second argument can specify the seek direction ios::beg the default Positioning relative to the beginning ios::cur Positioning relative to the current position ios::end Positioning relative to the end

20

2008 Pearson Education, Inc. All rights reserved.

17.5 Reading Data from a Sequential File (Cont.)


Member functions seekg and seekp (Cont.)
Examples fileObject.seekg( n ); Position to the nth byte of fileObject fileObject.seekg( n, ios::cur ); Position n bytes forward in fileobject fileObject.seekg( n, ios::end ); Position n bytes back from end of fileObject fileObject.seekg( 0, ios::end ); Position at end of fileObject

21

2008 Pearson Education, Inc. All rights reserved.

17.5 Reading Data from a Sequential File (Cont.)


File-position pointer (Cont.)
Member functions tellg and tellp (of istream and ostream, respectively)
Returns current position of the file-position pointer as type long

22

Example location = fileObject.tellg();

2008 Pearson Education, Inc. All rights reserved.

1 2 3 4 5 6 7 8 9

// Fig. 17.7: Fig17_07.cpp // Reading and printing a sequential file. #include <iostream> using std::cerr; using std::cout; using std::endl; using std::fixed; using std::ios; using std::left;

23

Outline

Fig17_07.cpp

(1 of 3)

10 using std::right; 11 using std::showpoint; 12 13 #include <fstream> // file stream 14 using std::ifstream; // input file stream 15 16 #include <iomanip> 17 using std::setw; 18 using std::setprecision; 19 20 #include <string> 21 using std::string; 22 23 #include <cstdlib> 24 using std::exit; // exit function prototype 25 26 void outputLine( int, const string, double ); // prototype

2008 Pearson Education, Inc. All rights reserved.

27 28 int main() 29 { 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 cout << left << setw( 10 ) << "Account" << setw( 13 ) << "Name" << "Balance" << endl << fixed << showpoint; // display each record in file while ( inClientFile >> account >> name >> balance ) outputLine( account, name, balance ); // ifstream constructor opens the file ifstream inClientFile( "clients.dat", ios::in ); // exit program if ifstream could not open file if ( !inClientFile ) { cerr << "File could not be opened" << endl; exit( 1 ); } // end if int account; char name[ 30 ]; double balance;

24

Outline
Open clients.dat for input
Fig17_07.cpp

(2 of 3) Overloaded operator! returns true if clients.dat was not opened successfully

Overloaded operator void * returns a null pointer 0 (false) when the end of clients.dat is reached

50 51 return 0; // ifstream destructor closes the file 52 } // end main

ifstream destructor implicitly closes the file


2008 Pearson Education, Inc. All rights reserved.

53 54 // display single record from file 55 void outputLine( int account, const string name, double balance ) 56 { 57 58 cout << left << setw( 10 ) << account << setw( 13 ) << name << setw( 7 ) << setprecision( 2 ) << right << balance << endl;

25

Outline

Fig17_07.cpp

59 } // end function outputLine Account 100 200 300 400 500 Name Jones Doe White Stone Rich Balance 24.98 345.67 0.00 -42.16 224.62

(3 of 3)

2008 Pearson Education, Inc. All rights reserved.

1 2 3 4 5 6 7 8 9 10

// Fig. 17.8: Fig17_08.cpp // Credit inquiry program. #include <iostream> using std::cerr; using std::cin; using using using using using std::cout; std::endl; std::fixed; std::ios; std::left;

26

Outline

Fig17_08.cpp

(1 of 6)

11 using std::right; 12 using std::showpoint; 13 14 #include <fstream> 15 using std::ifstream; 16 17 #include <iomanip> 18 using std::setw; 19 using std::setprecision; 20 21 #include <string> 22 using std::string; 23 24 #include <cstdlib> 25 using std::exit; // exit function prototype 26 27 enum RequestType { ZERO_BALANCE = 1, CREDIT_BALANCE, DEBIT_BALANCE, END }; 28 int getRequest(); 29 bool shouldDisplay( int, double ); 30 void outputLine( int, const string, double );

2008 Pearson Education, Inc. All rights reserved.

31 32 int main() 33 { 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 // ifstream constructor opens the file ifstream inClientFile( "clients.dat", ios::in ); // exit program if ifstream could not open file if ( !inClientFile ) { cerr << "File could not be opened" << endl; exit( 1 ); } // end if int request; int account; char name[ 30 ]; double balance; // get user's request (e.g., zero, credit or debit balance) request = getRequest();

27

Outline

Fig17_08.cpp

(2 of 6)

2008 Pearson Education, Inc. All rights reserved.

52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81

// process user's request while ( request != END ) { switch ( request ) { case ZERO_BALANCE: cout << "\nAccounts with zero balances:\n"; break; case CREDIT_BALANCE: cout << "\nAccounts with credit balances:\n"; break; case DEBIT_BALANCE: cout << "\nAccounts with debit balances:\n"; break; } // end switch // read account, name and balance from file inClientFile >> account >> name >> balance; // display file contents (until eof) while ( !inClientFile.eof() ) { // display record if ( shouldDisplay( request, balance ) ) outputLine( account, name, balance ); // read account, name and balance from file inClientFile >> account >> name >> balance; } // end inner while

28

Outline

Fig17_08.cpp

(3 of 6)

2008 Pearson Education, Inc. All rights reserved.

82 83 84 85 86

inClientFile.clear(); // reset eof for next input inClientFile.seekg( 0 ); // reposition to beginning of file request = getRequest(); // get additional request from user } // end outer while

29

Outline

87 cout << "End of run." << endl; 88 return 0; // ifstream destructor closes the file 89 } // end main 90 91 // obtain request from user 92 int getRequest() 93 { 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 do // input user request { cout << "\n? "; cin >> request; } while ( request < ZERO_BALANCE && request > END ); return request; int request; // request from user // display request options cout << "\nEnter request" << endl << << << << " " " " 1 2 3 4 -

Use ostream member function seekg to reposition the fileFig17_08.cpp position pointer to the beginning (4 of 6)

List accounts with zero balances" << endl List accounts with credit balances" << endl List accounts with debit balances" << endl End of run" << fixed << showpoint;

110 } // end function getRequest 111

2008 Pearson Education, Inc. All rights reserved.

112 // determine whether to display given record 113 bool shouldDisplay( int type, double balance ) 114 { 115 116 117 118 119 120 121 122 123 124 125 126 127 129 130 // display single record from file 131 void outputLine( int account, const string name, double balance ) 132 { 133 134 cout << left << setw( 10 ) << account << setw( 13 ) << name << setw( 7 ) << setprecision( 2 ) << right << balance << endl; return false; 128 } // end function shouldDisplay // determine whether to display debit balances if ( type == DEBIT_BALANCE && balance > 0 ) return true; // determine whether to display credit balances if ( type == CREDIT_BALANCE && balance < 0 ) return true; // determine whether to display zero balances if ( type == ZERO_BALANCE && balance == 0 ) return true;

30

Outline

Fig17_08.cpp

(5 of 6)

135 } // end function outputLine

2008 Pearson Education, Inc. All rights reserved.

Enter request 1 - List accounts with zero balances 2 - List accounts with credit balances 3 - List accounts with debit balances 4 - End of run ? 1 Accounts with zero balances: 300 White 0.00 Enter request 1 - List accounts with zero balances 2 - List accounts with credit balances 3 - List accounts with debit balances 4 - End of run ? 2 Accounts with credit balances: 400 Stone -42.16 Enter request 1 - List accounts with zero balances 2 - List accounts with credit balances 3 - List accounts with debit balances 4 - End of run ? 3 Accounts with debit balances: 100 Jones 24.98 200 Doe 345.67 500 Rich 224.62 Enter request 1 - List accounts with zero balances 2 - List accounts with credit balances 3 - List accounts with debit balances 4 - End of run ? 4 End of run.

31

Outline

Fig17_08.cpp

(6 of 6)

2008 Pearson Education, Inc. All rights reserved.

32

17.6 Updating Sequential Files


Updating a record in a sequential file
The new record could be longer than the old record
If it is, it could overwrite the next sequential record You would have to rewrite every record into another file Copy over all records before this one Write new version of this record Copy over all records after this one This might be acceptable if you are updating many records

2008 Pearson Education, Inc. All rights reserved.

33

17.7 Random-Access Files


Random-access files
Necessary for instant-access applications
Such as transaction-processing systems

A record can be inserted, deleted or modified without affecting other records

Various techniques can be used


Require that all records be of the same length, arranged in the order of the record keys Program can calculate the exact location of any record Base on the record size and record key

2008 Pearson Education, Inc. All rights reserved.

34

Fig. 17.9 | C++ view of a random-access file.

2008 Pearson Education, Inc. All rights reserved.

35

17.8 Creating a Random-Access File


ostream member function write
Writes a number of bytes from a location in memory to the stream
If the stream is associated with a file, the writing is at the put file-position pointer

First argument
A const char * pointing to bytes in memory

Second argument
A size_t specifying the number of bytes to write

Example
outFile.write( reinterpret_cast<const char *>( &number ), sizeof( number ) );
2008 Pearson Education, Inc. All rights reserved.

17.8 Creating a Random-Access File (Cont.)


Operator reinterpret_cast
Casts a pointer of one type to an unrelated type
Also converts between pointer and integer types Is performed at compile time
Does not change the value of the object pointed to

36

2008 Pearson Education, Inc. All rights reserved.

37

Error-Prevention Tip 17.1


It is easy to use reinterpret_cast to perform dangerous manipulations that could lead to serious execution-time errors.

2008 Pearson Education, Inc. All rights reserved.

38

Portability Tip 17.1


Using reinterpret_cast is compilerdependent and can cause programs to behave differently on different platforms. The reinterpret_cast operator should not be used unless absolutely necessary.

2008 Pearson Education, Inc. All rights reserved.

39

Portability Tip 17.2


A program that reads unformatted data (written by write) must be compiled and executed on a system compatible with the program that wrote the data, because different systems may represent internal data differently.

2008 Pearson Education, Inc. All rights reserved.

1 2 3 4 5 6 7 8 9

// Fig. 17.10: ClientData.h // Class ClientData definition used in Fig. 17.12Fig. 17.15. #ifndef CLIENTDATA_H #define CLIENTDATA_H #include <string> using std::string;

40

Outline

ClientData.h

(1 of 2)
class ClientData

10 { 11 public: 12 13 14 15 16 17 18 19 20 21 22 23 24 25 // accessor functions for firstName void setFirstName( string ); string getFirstName() const; // accessor functions for lastName void setLastName( string ); string getLastName() const; // accessor functions for accountNumber void setAccountNumber( int ); int getAccountNumber() const; // default ClientData constructor ClientData( int = 0, string = "", string = "", double = 0.0 );

2008 Pearson Education, Inc. All rights reserved.

26 27 28 29 31 32 33 34 36 37 #endif // accessor functions for balance void setBalance( double ); double getBalance() const; int accountNumber; char lastName[ 15 ]; char firstName[ 10 ]; double balance;

41

Outline

30 private:

ClientData.h

(2 of 2)

35 }; // end class ClientData

Store the first and last name in fixed-length char arrays we cannot use strings because they do not have uniform length

2008 Pearson Education, Inc. All rights reserved.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

// Fig. 17.11: ClientData.cpp // Class ClientData stores customer's credit information. #include <string> using std::string; #include "ClientData.h" // default ClientData constructor ClientData::ClientData( int accountNumberValue, string lastNameValue, string firstNameValue, double balanceValue ) { setAccountNumber( accountNumberValue ); setLastName( lastNameValue ); setFirstName( firstNameValue ); setBalance( balanceValue ); } // end ClientData constructor // get account-number value int ClientData::getAccountNumber() const { return accountNumber;

42

Outline

ClientData.cpp

(1 of 3)

22 } // end function getAccountNumber 23 24 // set account-number value 25 void ClientData::setAccountNumber( int accountNumberValue ) 26 { 27 accountNumber = accountNumberValue; // should validate 28 } // end function setAccountNumber

2008 Pearson Education, Inc. All rights reserved.

29 30 // get last-name value 31 string ClientData::getLastName() const 32 { 33 35 36 // set last-name value 37 void ClientData::setLastName( string lastNameString ) 38 { 39 40 41 42 43 44 46 47 // get first-name value 48 string ClientData::getFirstName() const 49 { 50 return firstName; 51 } // end function getFirstName // copy at most 15 characters from string to lastName const char *lastNameValue = lastNameString.data(); int length = lastNameString.size(); length = ( length < 15 ? length : 14 ); strncpy( lastName, lastNameValue, length ); lastName[ length ] = '\0'; // append null character to lastName return lastName; 34 } // end function getLastName

43

Outline

ClientData.cpp

(2 of 3)

string member function data returns an array containing the characters of the string (not guaranteed to be null terminated) string member function size returns the length of lastNameString

45 } // end function setLastName

2008 Pearson Education, Inc. All rights reserved.

52 53 // set first-name value 54 void ClientData::setFirstName( string firstNameString ) 55 { 56 57 58 59 60 61 63 64 // get balance value 65 double ClientData::getBalance() const 66 { 67 69 70 // set balance value 71 void ClientData::setBalance( double balanceValue ) 72 { 73 balance = balanceValue; 74 } // end function setBalance return balance; 68 } // end function getBalance // copy at most 10 characters from string to firstName const char *firstNameValue = firstNameString.data(); int length = firstNameString.size(); length = ( length < 10 ? length : 9 ); strncpy( firstName, firstNameValue, length ); firstName[ length ] = '\0'; // append null character to firstName

44

Outline

ClientData.cpp

(3 of 3)

62 } // end function setFirstName

2008 Pearson Education, Inc. All rights reserved.

1 2 3 4 5 6 7 8 9 10

// Fig. 17.12: Fig17_12.cpp // Creating a randomly accessed file. #include <iostream> using std::cerr; using std::endl; using std::ios; #include <fstream> using std::ofstream;

45

Outline

Fig17_12.cpp

(1 of 2)

11 #include <cstdlib> 12 using std::exit; // exit function prototype 13 14 #include "ClientData.h" // ClientData class definition 15

2008 Pearson Education, Inc. All rights reserved.

16 int main() 17 { 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 return 0; 35 } // end main // output 100 blank records to file for ( int i = 0; i < 100; i++ ) outCredit.write( reinterpret_cast< const char * >( &blankClient ), sizeof( ClientData ) ); ClientData blankClient; // constructor zeros out each data member // exit program if ofstream could not open file if ( !outCredit ) { cerr << "File could not be opened." << endl; exit( 1 ); } // end if ofstream outCredit( "credit.dat", ios::out | ios::binary );

46

Outline

Open credit.dat in binary mode, which is required to Fig17_12.cpp write fixed-length records
(2 of 2)

Write the data in blankClient to credit.dat as bytes

2008 Pearson Education, Inc. All rights reserved.

17.9 Writing Data Randomly to a Random-Access File


Writing data randomly
Opening for input and output in binary mode
Use an fstream object Combine file-open modes ios::in, ios::out and ios::binary

47

Separate each open mode from the next with the bitwise inclusive OR operator (|)

Use function seekp to set the put file-position pointer to the specific position
Example calculation ( n 1 ) * sizeof( ClientData ) Byte location for nth ClientData record

Use function write to output the data


2008 Pearson Education, Inc. All rights reserved.

1 2 3 4 5 6 7 8

// Fig. 17.13: Fig17_13.cpp // Writing to a random-access file. #include <iostream> using std::cerr; using std::cin; using std::cout; using std::endl; using std::ios;

48

Outline

Fig17_13.cpp

9 10 #include <iomanip> 11 using std::setw; 12 13 #include <fstream> 14 using std::fstream; 15 16 #include <cstdlib> 17 using std::exit; // exit function prototype 18 19 #include "ClientData.h" // ClientData class definition 20 21 int main() 22 { 23 int accountNumber; 24 char lastName[ 15 ]; 25 26 27 28 29 char firstName[ 10 ]; double balance;

(1 of 4)

Create fstream outCredit to open credit.dat for input and output in binary mode

fstream outCredit( "credit.dat", ios::in | ios::out | ios::binary );

2008 Pearson Education, Inc. All rights reserved.

30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57

// exit program if fstream cannot open file if ( !outCredit ) { cerr << "File could not be opened." << endl; exit( 1 ); } // end if cout << "Enter account number (1 to 100, 0 to end input)\n? "; // require user to specify account number ClientData client; cin >> accountNumber; // user enters information, which is copied into file while ( accountNumber > 0 && accountNumber <= 100 ) { // user enters last name, first name and balance cout << "Enter lastname, firstname, balance\n? "; cin >> setw( 15 ) >> lastName; cin >> setw( 10 ) >> firstName; cin >> balance; // set record accountNumber, lastName, firstName and balance values client.setAccountNumber( accountNumber ); client.setLastName( lastName ); client.setFirstName( firstName ); client.setBalance( balance );

49

Outline

Fig17_13.cpp

(2 of 4)

2008 Pearson Education, Inc. All rights reserved.

58 59 60 61 62 63 64 65 66 67 68 69 70 71

// seek position in file of user-specified record outCredit.seekp( ( client.getAccountNumber() - 1 ) * sizeof( ClientData ) ); // write user-specified information in file outCredit.write( reinterpret_cast< const char * >( &client ), sizeof( ClientData ) );

50

Position the put fileposition pointer to the desired byte location


Fig17_13.cpp

Outline

(3 of 4)
// enable user to enter another account cout << "Enter account number\n? "; cin >> accountNumber; } // end while return 0;

Write the ClientData record to the correct position in the file

72 } // end main

2008 Pearson Education, Inc. All rights reserved.

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

51

Outline

Fig17_13.cpp

(4 of 4)

2008 Pearson Education, Inc. All rights reserved.

17.10 Reading from a Random-Access File Sequentially


Sequentially reading a random-access file
Ifstream member function read
Inputs a number of bytes from the current file position in the stream into an object First argument A char * pointing to the object in memory Second argument A size_t specifying the number of bytes to input

52

Additional benefit
Sequentially read-in records are sorted in order of ascending record keys Space-time trade off: a fast sorting algorithm, but spaceconsuming
2008 Pearson Education, Inc. All rights reserved.

1 2 3 4 5 6 7 8

// Fig. 17.14: Fig17_14.cpp // Reading a random access file sequentially. #include <iostream> using std::cerr; using std::cout; using std::endl; using std::fixed; using std::ios;

53

Outline

Fig17_14.cpp

9 using std::left; 10 using std::right; 11 using std::showpoint; 12 13 #include <iomanip> 14 using std::setprecision; 15 using std::setw; 16 17 #include <fstream> 18 using std::ifstream; 19 using std::ostream; 20 21 #include <cstdlib> 22 using std::exit; // exit function prototype 23 24 #include "ClientData.h" // ClientData class definition 25 26 void outputLine( ostream&, const ClientData & ); // prototype 27

(1 of 3)

2008 Pearson Education, Inc. All rights reserved.

28 int main() 29 { 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 // read first record from file inCredit.read( reinterpret_cast< char * >( &client ), sizeof( ClientData ) ); // read all records from file while ( inCredit && !inCredit.eof() ) { // display record if ( client.getAccountNumber() != 0 ) outputLine( cout, client ); ifstream inCredit( "credit.dat", ios::in | ios::binary ); // exit program if ifstream cannot open file if ( !inCredit ) { cerr << "File could not be opened." << endl; exit( 1 ); } // end if cout << left << setw( 10 ) << "Account" << setw( 16 ) << "Last Name" << setw( 11 ) << "First Name" << left << setw( 10 ) << right << "Balance" << endl; ClientData client; // create record

54

Outline

Fig17_14.cpp

(2 of 3)

This loop-continuation condition evaluates to false if an error occurs when reading from the file or if the end of file is reached

2008 Pearson Education, Inc. All rights reserved.

56 57 58 59 60 61 63

// read next from file inCredit.read( reinterpret_cast< char * >( &client ), sizeof( ClientData ) ); } // end while return 0;

55

Outline

62 } // end main 64 // display single record

Because outputLine takes an ostream reference as argument, it can be used with cout (an Fig17_14.cpp ostream object) or an ofstream object (derived from ostream) to output to the screen or to a file (3 of 3)

65 void outputLine( ostream &output, const ClientData &record ) 66 { 67 68 69 70 71 output << left << setw( 10 ) << record.getAccountNumber() << setw( 16 ) << record.getLastName() << setw( 11 ) << record.getFirstName() << setw( 10 ) << setprecision( 2 ) << right << fixed << showpoint << record.getBalance() << endl;

72 } // end function outputLine Account 29 33 37 88 96 Last Name Brown Dunn Barker Smith Stone First Name Nancy Stacey Doug Dave Sam Balance -24.54 314.33 0.00 258.34 34.98

2008 Pearson Education, Inc. All rights reserved.

17.11 Case Study: A TransactionProcessing Program

56

2008 Pearson Education, Inc. All rights reserved.

1 2 3 4 5 6 7 8

// Fig. 17.15: Fig17_15.cpp // This program reads a random access file sequentially, updates // data previously written to the file, creates data to be placed // in the file, and deletes data previously in the file. #include <iostream> using std::cerr; using std::cin; using std::cout;

57

Outline

Fig17_15.cpp

9 using std::endl; 10 using std::fixed; 11 using std::ios; 12 13 14 15 16 17 using std::left; using std::right; using std::showpoint; #include <fstream> using std::ofstream;

(1 of 10)

18 using std::ostream; 19 using std::fstream; 20 21 #include <iomanip> 22 using std::setw; 23 using std::setprecision; 24 25 #include <cstdlib> 26 using std::exit; // exit function prototype 27 28 #include "ClientData.h" // ClientData class definition 29

2008 Pearson Education, Inc. All rights reserved.

30 int enterChoice(); 31 void createTextFile( fstream& ); 32 void updateRecord( fstream& ); 33 void newRecord( fstream& ); 34 void deleteRecord( fstream& ); 35 void outputLine( ostream&, const ClientData & ); 36 int getAccount( const char * const ); 37 38 enum Choices { PRINT = 1, UPDATE, NEW, DELETE, END }; 39 40 int main() 41 { 42 43 44 45 46 47 48 49 50 51 52 53 int choice; // store user choice // exit program if fstream cannot open file if ( !inOutCredit ) { cerr << "File could not be opened." << endl; exit ( 1 ); } // end if // open file for reading and writing fstream inOutCredit( "credit.dat", ios::in | ios::out | ios::binary );

58

Outline

Fig17_15.cpp

(2 of 10)

Or together modes ios::in and ios::out for both reading and writing capabilities

2008 Pearson Education, Inc. All rights reserved.

54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78

// enable user to specify action while ( ( choice = enterChoice() ) != END ) { switch ( choice ) { case PRINT: // create text file from record file createTextFile( inOutCredit ); break; case UPDATE: // update record updateRecord( inOutCredit ); break; case NEW: // create record newRecord( inOutCredit ); break; case DELETE: // delete existing record deleteRecord( inOutCredit ); break; default: // display error if user does not select valid choice cerr << "Incorrect choice" << endl; break; } // end switch inOutCredit.clear(); // reset end-of-file indicator } // end while

59

Outline

Fig17_15.cpp

(3 of 10)

79 return 0; 80 } // end main 81

2008 Pearson Education, Inc. All rights reserved.

82 // enable user to input menu choice 83 int enterChoice() 84 { 85 86 87 88 89 90 91 92 93 94 95 96 int menuChoice; cin >> menuChoice; // input menu selection from user return menuChoice; // display available options cout << "\nEnter your choice" << endl << "1 - store a formatted text file of accounts" << endl << " called \"print.txt\" for printing" << endl << "2 - update an account" << endl << "3 - add a new account" << endl << "4 - delete an account" << endl << "5 - end program\n? ";

60

Outline

Fig17_15.cpp

(4 of 10)

97 } // end function enterChoice 98 99 // create formatted text file for printing 100 void createTextFile( fstream &readFromFile ) 101 { 102 // create text file 103 ofstream outPrintFile( "print.txt", ios::out ); 104 105 106 107 108 109 110 111 // exit program if ofstream cannot create file if ( !outPrintFile ) { cerr << "File could not be created." << endl; exit( 1 ); } // end if

fstream object argument for inputting data from credit.dat

2008 Pearson Education, Inc. All rights reserved.

112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134

outPrintFile << left << setw( 10 ) << "Account" << setw( 16 ) << "Last Name" << setw( 11 ) << "First Name" << right << setw( 10 ) << "Balance" << endl; // set file-position pointer to beginning of readFromFile readFromFile.seekg( 0 );

61

Outline

// read first record from record file ClientData client; readFromFile.read( reinterpret_cast< char * >( &client ), sizeof( ClientData ) ); // copy all records from record file into text file while ( !readFromFile.eof() ) { // write single record to text file

Use istream member function seekg Fig17_15.cpp to ensure that the file-position pointer is at the beginning of the file (5 of 10)

if ( client.getAccountNumber() != 0 ) // skip empty records outputLine( outPrintFile, client ); // read next record from record file readFromFile.read( reinterpret_cast< char * >( &client ), sizeof( ClientData ) ); } // end while

135 } // end function createTextFile 136 137 // update balance in record 138 void updateRecord( fstream &updateFile ) 139 { 140 141 // obtain number of account to update int accountNumber = getAccount( "Enter account to update" );

2008 Pearson Education, Inc. All rights reserved.

142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 // move file-position pointer to correct record in file updateFile.seekg( ( accountNumber - 1 ) * sizeof( ClientData ) ); // read first record from file ClientData client; updateFile.read( reinterpret_cast< char * >( &client ), sizeof( ClientData ) ); // update record if ( client.getAccountNumber() != 0 ) { outputLine( cout, client ); // display the record // request user to specify transaction cout << "\nEnter charge (+) or payment (-): "; double transaction; // charge or payment cin >> transaction; // update record balance double oldBalance = client.getBalance(); client.setBalance( oldBalance + transaction ); outputLine( cout, client ); // display the record // move file-position pointer to correct record in file updateFile.seekp( ( accountNumber - 1 ) * sizeof( ClientData ) );

62

Outline

Fig17_15.cpp

(6 of 10) Read data into object client, using istream member function read Determine whether the record contains information Use function outputLine with the cout ostream object to display the record

2008 Pearson Education, Inc. All rights reserved.

169 170 171 172 173

// write updated record over old record in file updateFile.write( reinterpret_cast< const char * >( &client ), sizeof( ClientData ) ); } // end if else // display error if account does not exist

63

Outline

174 cerr << "Account #" << accountNumber 175 << " has no information." << endl; 176 } // end function updateRecord 177 178 // create and insert record 179 void newRecord( fstream &insertInFile ) 180 { 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 // obtain number of account to create int accountNumber = getAccount( "Enter new account number" ); // move file-position pointer to correct record in file insertInFile.seekg( ( accountNumber - 1 ) * sizeof( ClientData ) ); // read record from file ClientData client; insertInFile.read( reinterpret_cast< char * >( &client ), sizeof( ClientData ) ); // create record, if record does not previously exist if ( client.getAccountNumber() == 0 ) { char lastName[ 15 ]; char firstName[ 10 ]; double balance;

Fig17_15.cpp

(7 of 10)

2008 Pearson Education, Inc. All rights reserved.

199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219

// user enters last name, first name and balance cout << "Enter lastname, firstname, balance\n? "; cin >> setw( 15 ) >> lastName; cin >> setw( 10 ) >> firstName; cin >> balance; // use values to populate account values client.setLastName( lastName ); client.setFirstName( firstName ); client.setBalance( balance ); client.setAccountNumber( accountNumber ); // move file-position pointer to correct record in file insertInFile.seekp( ( accountNumber - 1 ) * sizeof( ClientData ) ); // insert record in file insertInFile.write( reinterpret_cast< const char * >( &client ), sizeof( ClientData ) ); } // end if else // display error if account already exists cerr << "Account #" << accountNumber

64

Outline

Fig17_15.cpp

(8 of 10)

220 << " already contains information." << endl; 221 } // end function newRecord 222 223 // delete an existing record 224 void deleteRecord( fstream &deleteFromFile ) 225 { 226 // obtain number of account to delete 227 228

Display an error message indicating that the account exists

int accountNumber = getAccount( "Enter account to delete" );

2008 Pearson Education, Inc. All rights reserved.

229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 256

// move file-position pointer to correct record in file deleteFromFile.seekg( ( accountNumber - 1 ) * sizeof( ClientData ) ); // read record from file ClientData client; deleteFromFile.read( reinterpret_cast< char * >( &client ), sizeof( ClientData ) ); // delete record, if record exists in file if ( client.getAccountNumber() != 0 ) { ClientData blankClient; // create blank record // move file-position pointer to correct record in file deleteFromFile.seekp( ( accountNumber - 1 ) * sizeof( ClientData ) ); // replace existing record with blank record deleteFromFile.write( reinterpret_cast< const char * >( &blankClient ), sizeof( ClientData ) ); cout << "Account #" << accountNumber << " deleted.\n"; } // end if else // display error if record does not exist cerr << "Account #" << accountNumber << " is empty.\n";

65

Outline

Fig17_15.cpp

(9 of 10)

Copy an empty record into the file to reinitialize that account

If the specified account is empty, display an error message

255 } // end deleteRecord

2008 Pearson Education, Inc. All rights reserved.

257 // display single record 258 void outputLine( ostream &output, const ClientData &record ) 259 { 260 261 262 output << left << setw( 10 ) << record.getAccountNumber() << setw( 16 ) << record.getLastName() << setw( 11 ) << record.getFirstName()

66

Outline

263 << setw( 10 ) << setprecision( 2 ) << right << fixed 264 << showpoint << record.getBalance() << endl; 265 } // end function outputLine 266 267 // obtain account-number value from user 268 int getAccount( const char * const prompt ) 269 { 270 int accountNumber; 271 272 273 274 275 276 277 278 279 // obtain account-number value do { cout << prompt << " (1 - 100): "; cin >> accountNumber; } while ( accountNumber < 1 || accountNumber > 100 ); return accountNumber;

Fig17_15.cpp

(10 of 10)

280 } // end function getAccount

2008 Pearson Education, Inc. All rights reserved.

You might also like