1
Chapter 14 - File Processing
Outline
14.1 Introduction
14.2 The Data Hierarchy
14.3 Files and Streams
14.4 Creating a Sequential-Access File
14.5 Reading Data from a Sequential-Access File
14.6 Updating Sequential-Access Files
14.7 Random-Access Files
14.8 Creating a Random-Access File
14.9 Writing Data Randomly to a Random-Access File
14.10 Reading Data Sequentially from a Random-Access File
14.11 Example: A Transaction-Processing Program
14.12 Input/Output of Objects
© 2003 Prentice Hall, Inc. All rights reserved.
2
14.1 Introduction
• Storage of data
– Arrays, variables are temporary
– Files are permanent
• Magnetic disk, optical disk, tapes
• In this chapter
– Create, update, process files
– Sequential and random access
– Formatted and raw processing
© 2003 Prentice Hall, Inc. All rights reserved.
3
14.2 The Data Hierarchy
• From smallest to largest
– Bit (binary digit)
• 1 or 0
• Everything in computer ultimately represented as bits
• Cumbersome for humans to use
• Character set
– Digits, letters, symbols used to represent data
– Every character represented by 1's and 0's
– Byte: 8 bits
• Can store a character (char)
• Also Unicode for large character sets (wchar_t)
© 2003 Prentice Hall, Inc. All rights reserved.
4
14.2 The Data Hierarchy
• From smallest to largest (continued)
– Field: group of characters with some meaning
• Your name
– Record: group of related fields
• struct or class in C++
• In payroll system, could be name, SS#, address, wage
• Each field associated with same employee
• Record key: field used to uniquely identify record
– File: group of related records
• Payroll for entire company
• Sequential file: records stored by key
– Database: group of related files
• Payroll, accounts-receivable, inventory…
© 2003 Prentice Hall, Inc. All rights reserved.
5
14.2 The Data Hierarchy
Sally Black
Tom Blue
Judy Green File
Iris Orange
Randy Red
Judy Green Record
Judy Field
01001010 Byte (ASCII character J)
1 Bit
© 2003 Prentice Hall, Inc. All rights reserved.
6
14.3 Files and Streams
• C++ views file as sequence of bytes
– Ends with end-of-file marker
0 1 2 3 4 5 6 7 8 9 ... n-1
... end-of-file marker
• When file opened
– Object created, stream associated with it
– cin, cout, etc. created when <iostream> included
• Communication between program and file/device
© 2003 Prentice Hall, Inc. All rights reserved.
7
14.3 Files and Streams
• To perform file processing
– Include <iostream> and <fstream>
– Class templates
• basic_ifstream (input)
• basic_ofstream (output)
• basic_fstream (I/O)
– typedefs for specializations that allow char I/O
• ifstream (char input)
• ofstream (char output)
• fstream (char I/O)
© 2003 Prentice Hall, Inc. All rights reserved.
8
14.3 Files and Streams
• Opening files
– Create objects from template
– Derive from stream classes
• Can use stream methods from Ch. 12
• put, get, peek, etc.
basic_ios
basic_istream basic_ostream
basic_ifstream basic_iostream basic_ofstream
basic_fstream
© 2003 Prentice Hall, Inc. All rights reserved.
9
14.4 Creating a Sequential-Access File
• C++ imposes no structure on file
– Concept of "record" must be implemented by programmer
• To open file, create objects
– Creates "line of communication" from object to file
– Classes
• ifstream (input only)
• ofstream (output only)
• fstream (I/O)
– Constructors take file name and file-open mode
ofstream outClientFile( "filename", fileOpenMode );
– To attach a file later
Ofstream outClientFile;
[Link]( "filename", fileOpenMode);
© 2003 Prentice Hall, Inc. All rights reserved.
10
14.4 Creating a Sequential-Access File
• File-open modes
– ofstream opened for output by default
• ofstream outClientFile( "[Link]", ios::out );
• ofstream outClientFile( "[Link]");
© 2003 Prentice Hall, Inc. All rights reserved.
11
14.4 Creating a Sequential-Access File
• Operations
– Overloaded operator!
• !outClientFile
• Returns nonzero (true) if badbit or failbit set
– Opened non-existent file for reading, wrong permissions
– Overloaded operator void*
• Converts stream object to pointer
• 0 when when failbit or badbit set, otherwise nonzero
– failbit set when EOF found
• while ( cin >> myVariable )
– Implicitly converts cin to pointer
– Loops until EOF
© 2003 Prentice Hall, Inc. All rights reserved.
12
14.4 Creating a Sequential-Access File
• Operations
– Writing to file (just like cout)
• outClientFile << myVariable
– Closing file
• [Link]()
• Automatically closed when destructor called
© 2003 Prentice Hall, Inc. All rights reserved.
13
1
2
// Fig. 14.4: fig14_04.cpp
// Create a sequential file.
Outline
3 #include <iostream>
4
fig14_04.cpp
5 using std::cout;
6 using std::cin;
(1 of 2)
7 using std::ios;
8 using std::cerr;
9 using std::endl;
10
11 #include <fstream>
12 Notice the the header files
13 using std::ofstream; required for file I/O.
14
15 #include <cstdlib> // exit prototype ofstream object created
16 and used to open file
17 int main()
"[Link]". If the file
18 {
19 // ofstream constructor opens file
does not exist, it is created.
20 ofstream outClientFile( "[Link]", ios::out );
21 ! operator used to test if the
22 // exit program if unable to create file
file opened properly.
23 if ( !outClientFile ) { // overloaded ! operator
24 cerr << "File could not be opened" << endl;
25 exit( 1 );
26
27 } // end if
© 2003 Prentice Hall, Inc.
All rights reserved.
14
28
29 cout << "Enter the account, name, and balance." << endl
Outline
30 << "Enter end-of-file to end input.\n? ";
cin is implicitly converted to
31
a pointer. When EOF is fig14_04.cpp
32 int account;
33 char name[ 30 ]; encountered, it returns 0 and (2 of 2)
34 double balance; the loop stops.
35
36 // read account, name and balance from cin, then place in file
37 while ( cin >> account >> name >> balance ) {
38 outClientFile << account << ' ' << name << ' ' << balance
39 << endl;
40 cout << "? ";
41
42 } // end while
Write data to file like a
43 regular stream.
44 return 0; // ofstream destructor closes file
45
46 } // end main File closed when destructor
called for object. Can be
explicitly closed with
close().
© 2003 Prentice Hall, Inc.
All rights reserved.
15
Enter
Enter
the account, name, and balance.
end-of-file to end input.
Outline
? 100 Jones 24.98
? 200 Doe 345.67
fig14_04.cpp
? 300 White 0.00
? 400 Stone -42.16
output (1 of 1)
? 500 Rich 224.62
? ^Z
© 2003 Prentice Hall, Inc.
All rights reserved.
16
14.5 Reading Data from a
Sequential-Access File
• Reading files
– ifstream inClientFile( "filename", ios::in );
– Overloaded !
• !inClientFile tests if file was opened properly
– operator void* converts to pointer
• while (inClientFile >> myVariable)
• Stops when EOF found (gets value 0)
© 2003 Prentice Hall, Inc. All rights reserved.
17
1
2
// Fig. 14.7: fig14_07.cpp
// Reading and printing a sequential file.
Outline
3 #include <iostream>
4
fig14_07.cpp
5 using std::cout;
6 using std::cin;
(1 of 3)
7 using std::ios;
8 using std::cerr;
9 using std::endl;
10 using std::left;
11 using std::right;
12 using std::fixed;
13 using std::showpoint;
14
15 #include <fstream>
16
17 using std::ifstream;
18
19 #include <iomanip>
20
21 using std::setw;
22 using std::setprecision;
23
24 #include <cstdlib> // exit prototype
25
26 void outputLine( int, const char * const, double );
27
© 2003 Prentice Hall, Inc.
All rights reserved.
18
28 int main()
29 {
Outline
30 // ifstream constructor opens the file Open and test file for input.
31 ifstream inClientFile( "[Link]", ios::in );
fig14_07.cpp
32
33 // exit program if ifstream could not open file
(2 of 3)
34 if ( !inClientFile ) {
35 cerr << "File could not be opened" << endl;
36 exit( 1 );
37
38 } // end if
39
40 int account;
41 char name[ 30 ];
42 double balance;
43
44 cout << left << setw( 10 ) << "Account" << setw( 13 )
45 Read
<< "Name" << "Balance" << endl << from
fixed <<file until EOF
showpoint;
46 found.
47 // display each record in file
48 while ( inClientFile >> account >> name >> balance )
49 outputLine( account, name, balance );
50
51 return 0; // ifstream destructor closes the file
52
53 } // end main
© 2003 Prentice Hall, Inc.
All rights reserved.
19
54
55 // display single record from file
Outline
56 void outputLine( int account, const char * const name,
57 double balance )
fig14_07.cpp
58 {
59 cout << left << setw( 10 ) << account << setw( 13 ) << name
(3 of 3)
60 << setw( 7 ) << setprecision( 2 ) << right << balance
61 << endl; fig14_07.cpp
62 output (1 of 1)
63 } // end function outputLine
Account Name Balance
100 Jones 24.98
200 Doe 345.67
300 White 0.00
400 Stone -42.16
500 Rich 224.62
© 2003 Prentice Hall, Inc.
All rights reserved.
20
14.5 Reading Data from a
Sequential-Access File
• File position pointers
– Number of next byte to read/write
– Functions to reposition pointer
• seekg (seek get for istream class)
• seekp (seek put for ostream class)
• Classes have "get" and "put" pointers
– seekg and seekp take offset and direction
• Offset: number of bytes relative to direction
• Direction (ios::beg default)
– ios::beg - relative to beginning of stream
– ios::cur - relative to current position
– ios::end - relative to end
© 2003 Prentice Hall, Inc. All rights reserved.
21
14.5 Reading Data from a
Sequential-Access File
• Examples
– [Link](0)
• Goes to front of file (location 0) because ios::beg is default
– [Link](n)
• Goes to nth byte from beginning
– [Link](n, ios::cur)
• Goes n bytes forward
– [Link](y, ios::end)
• Goes y bytes back from end
– [Link](0, ios::cur)
• Goes to last byte
– seekp similar
© 2003 Prentice Hall, Inc. All rights reserved.
22
14.5 Reading Data from a
Sequential-Access File
• To find pointer location
– tellg and tellp
– location = [Link]()
• Upcoming example
– Credit manager program
– List accounts with zero balance, credit, and debit
© 2003 Prentice Hall, Inc. All rights reserved.
23
1
2
// Fig. 14.8: fig14_08.cpp
// Credit-inquiry program.
Outline
3 #include <iostream>
4
fig14_08.cpp
5 using std::cout;
6 using std::cin;
(1 of 6)
7 using std::ios;
8 using std::cerr;
9 using std::endl;
10 using std::fixed;
11 using std::showpoint;
12 using std::left;
13 using std::right;
14
15 #include <fstream>
16
17 using std::ifstream;
18
19 #include <iomanip>
20
21 using std::setw;
22 using std::setprecision;
23
24 #include <cstdlib>
25
© 2003 Prentice Hall, Inc.
All rights reserved.
24
26
27
enum RequestType { ZERO_BALANCE = 1, CREDIT_BALANCE,
DEBIT_BALANCE, END };
Outline
28 int getRequest();
29 bool shouldDisplay( int, double );
fig14_08.cpp
30 void outputLine( int, const char * const, double );
31
(2 of 6)
32 int main()
33 {
34 // ifstream constructor opens the file
35 ifstream inClientFile( "[Link]", ios::in );
36
37 // exit program if ifstream could not open file
38 if ( !inClientFile ) {
39 cerr << "File could not be opened" << endl;
40 exit( 1 );
41
42 } // end if
43
44 int request;
45 int account;
46 char name[ 30 ];
47 double balance;
48
49 // get user's request (e.g., zero, credit or debit balance)
50 request = getRequest();
51
© 2003 Prentice Hall, Inc.
All rights reserved.
25
52
53
// process user's request
while ( request != END ) {
Outline
54
55 switch ( request ) {
fig14_08.cpp
56
57 case ZERO_BALANCE:
(3 of 6)
58 cout << "\nAccounts with zero balances:\n";
59 break;
60
61 case CREDIT_BALANCE:
62 cout << "\nAccounts with credit balances:\n";
63 break;
64
65 case DEBIT_BALANCE:
66 cout << "\nAccounts with debit balances:\n";
67 break;
68
69 } // end switch
70
© 2003 Prentice Hall, Inc.
All rights reserved.
26
71
72
// read account, name and balance from file
inClientFile >> account >> name >> balance;
Outline
73
74 // display file contents (until eof)
fig14_08.cpp
75 while ( ![Link]() ) {
76
(4 of 6)
77 // display record
78 if ( shouldDisplay( request, balance ) )
79 outputLine( account, name, balance );
80
81 // read account, name and balance from file
82 inClientFile >> account >> name >> balance;
83 Use clear to reset eof. Use
84 } // end inner while seekg to set file position
85 pointer to beginning of file.
86 [Link](); // reset eof for next input
87 [Link]( 0 ); // move to beginning of file
88 request = getRequest(); // get additional request from user
89
90 } // end outer while
91
92 cout << "End of run." << endl;
93
94 return 0; // ifstream destructor closes the file
95
96 } // end main
© 2003 Prentice Hall, Inc.
All rights reserved.
27
97
98 // obtain request from user
Outline
99 int getRequest()
100 {
fig14_08.cpp
101 int request;
102
(5 of 6)
103 // display request options
104 cout << "\nEnter request" << endl
105 << " 1 - List accounts with zero balances" << endl
106 << " 2 - List accounts with credit balances" << endl
107 << " 3 - List accounts with debit balances" << endl
108 << " 4 - End of run" << fixed << showpoint;
109
110 // input user request
111 do {
112 cout << "\n? ";
113 cin >> request;
114
115 } while ( request < ZERO_BALANCE && request > END );
116
117 return request;
118
119 } // end function getRequest
120
© 2003 Prentice Hall, Inc.
All rights reserved.
28
121
122
// determine whether to display given record
bool shouldDisplay( int type, double balance )
Outline
123 {
124 // determine whether to display credit balances
fig14_08.cpp
125 if ( type == CREDIT_BALANCE && balance < 0 )
126 return true;
(6 of 6)
127
128 // determine whether to display debit balances
129 if ( type == DEBIT_BALANCE && balance > 0 )
130 return true;
131
132 // determine whether to display zero balances
133 if ( type == ZERO_BALANCE && balance == 0 )
134 return true;
135
136 return false;
137
138 } // end function shouldDisplay
139
140 // display single record from file
141 void outputLine( int account, const char * const name,
142 double balance )
143 {
144 cout << left << setw( 10 ) << account << setw( 13 ) << name
145 << setw( 7 ) << setprecision( 2 ) << right << balance
146 << endl;
147
148 } // end function outputLine
© 2003 Prentice Hall, Inc.
All rights reserved.
29
Enter request
1 - List accounts with zero balances
Outline
2 - List accounts with credit balances
3 - List accounts with debit balances
fig14_08.cpp
4 - End of run
? 1
output (1 of 2)
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
© 2003 Prentice Hall, Inc.
All rights reserved.
30
Enter request
1 - List accounts with zero balances
Outline
2 - List accounts with credit balances
3 - List accounts with debit balances
fig14_08.cpp
4 - End of run
? 3
output (2 of 2)
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.
© 2003 Prentice Hall, Inc.
All rights reserved.
31
14.6 Updating Sequential-Access Files
• Updating sequential files
– Risk overwriting other data
– Example: change name "White" to "Worthington"
• Old data
300 White 0.00 400 Jones 32.87
• Insert new data
300 Worthington 0.00
300 White 0.00 400 Jones 32.87
Data gets overwritten
300 Worthington 0.00ones 32.87
– Formatted text different from internal representation
– Problem can be avoided, but awkward
© 2003 Prentice Hall, Inc. All rights reserved.
32
14.7 Random-Access Files
• Instant access
– Want to locate record quickly
• Airline reservations, ATMs
– Sequential files must search through each one
• Random-access files are solution
– Instant access
– Insert record without destroying other data
– Update/delete items without changing other data
© 2003 Prentice Hall, Inc. All rights reserved.
33
14.7 Random-Access Files
• C++ imposes no structure on files
– Programmer must create random-access files
– Simplest way: fixed-length records
• Calculate position in file from record size and key
© 2003 Prentice Hall, Inc. All rights reserved.
34
14.8 Creating a Random-Access File
• "1234567" (char *) vs 1234567 (int)
– char * takes 8 bytes (1 for each character + null)
– int takes fixed number of bytes (perhaps 4)
• 123 same size in bytes as 1234567
• << operator and write()
– outFile << number
• Outputs number (int) as a char *
• Variable number of bytes
– [Link]( const char *, size );
• Outputs raw bytes
• Takes pointer to memory location, number of bytes to write
– Copies data directly from memory into file
– Does not convert to char *
© 2003 Prentice Hall, Inc. All rights reserved.
35
14.8 Creating a Random-Access File
• Example
[Link]( reinterpret_cast<const char *>(&number),
sizeof( number ) );
– &number is an int *
• Convert to const char * with reinterpret_cast
– sizeof(number)
• Size of number (an int) in bytes
– read function similar (more later)
– Must use write/read between compatible machines
• Only when using raw, unformatted data
– Use ios::binary for raw writes/reads
© 2003 Prentice Hall, Inc. All rights reserved.
36
14.8 Creating a Random-Access File
• Usually write entire struct or object to file
• Problem statement
– Credit processing program
– Store at most 100 fixed-length records
– Record
• Account number (key)
• First and last name
• Balance
– Account operations
• Update, create new, delete, list all accounts in a file
• Next: program to create blank 100-record file
© 2003 Prentice Hall, Inc. All rights reserved.
37
1
2
// Fig. 14.10: clientData.h
// Class ClientData definition used in Fig. 14.12–Fig. 14.15.
Outline
3 #ifndef CLIENTDATA_H
4 #define CLIENTDATA_H
Class ClientData stores clientData.h
5
6 #include <iostream>
the information for each (1 of 2)
7 person. 100 blank
8 using std::string; ClientData objects will be
9 written to a file.
10 class ClientData {
11
12 public:
13
14 // default ClientData constructor
15 ClientData( int = 0, string = "", string = "", double = 0.0 );
16
17 // accessor functions for accountNumber
18 void setAccountNumber( int );
19 int getAccountNumber() const;
20
21 // accessor functions for lastName
22 void setLastName( string );
23 string getLastName() const;
24
© 2003 Prentice Hall, Inc.
All rights reserved.
38
25
26
// accessor functions for firstName
void setFirstName( string );
Outline
27 string getFirstName() const;
28
clientData.h
29 // accessor functions for balance
30 void setBalance( double );
(2 of 2)
31 double getBalance() const;
32 Put limits on the size of the
33 private: first and last name.
34 int accountNumber; accountNumber (an int)
35 char lastName[ 15 ];
and balance (double) are
36 char firstName[ 10 ];
37 double balance;
already of a fixed size.
38
39 }; // end class ClientData
40
41 #endif
© 2003 Prentice Hall, Inc.
All rights reserved.
39
1
2
// Fig. 14.11: [Link]
// Class ClientData stores customer's credit information.
Outline
3 #include <iostream>
4
[Link]
5 using std::string;
6
(1 of 4)
7 #include <cstring>
8 #include "clientData.h"
9
10 // default ClientData constructor
11 ClientData::ClientData( int accountNumberValue,
12 string lastNameValue, string firstNameValue,
13 double balanceValue )
14 {
15 setAccountNumber( accountNumberValue );
16 setLastName( lastNameValue );
17 setFirstName( firstNameValue );
18 setBalance( balanceValue );
19
20 } // end ClientData constructor
21
22 // get account-number value
23 int ClientData::getAccountNumber() const
24 {
25 return accountNumber;
26
27 } // end function getAccountNumber
© 2003 Prentice Hall, Inc.
All rights reserved.
40
28
29 // set account-number value
Outline
30 void ClientData::setAccountNumber( int accountNumberValue )
31 {
[Link]
32 accountNumber = accountNumberValue;
33
(2 of 4)
34 } // end function setAccountNumber
35
36 // get last-name value
37 string ClientData::getLastName() const
38 {
39 return lastName;
40
41 } // end function getLastName
42
43 // set last-name value
44 void ClientData::setLastName( string lastNameString )
45 {
46 // copy at most 15 characters from string to lastName
47 const char *lastNameValue = [Link]();
48 int length = strlen( lastNameValue );
49 length = ( length < 15 ? length : 14 );
50 strncpy( lastName, lastNameValue, length );
51
52 // append null character to lastName
53 lastName[ length ] = '\0';
© 2003 Prentice Hall, Inc.
All rights reserved.
41
54
55 } // end function setLastName
Outline
56
57 // get first-name value
[Link]
58 string ClientData::getFirstName() const
59 {
(3 of 4)
60 return firstName;
61
62 } // end function getFirstName
63
64 // set first-name value
65 void ClientData::setFirstName( string firstNameString )
66 {
67 // copy at most 10 characters from string to firstName
68 const char *firstNameValue = [Link]();
69 int length = strlen( firstNameValue );
70 length = ( length < 10 ? length : 9 );
71 strncpy( firstName, firstNameValue, length );
72
73 // append new-line character to firstName
74 firstName[ length ] = '\0';
75
76 } // end function setFirstName
77
© 2003 Prentice Hall, Inc.
All rights reserved.
42
78
79
// get balance value
double ClientData::getBalance() const
Outline
80 {
81 return balance;
[Link]
82
83 } // end function getBalance
(4 of 4)
84
85 // set balance value
86 void ClientData::setBalance( double balanceValue )
87 {
88 balance = balanceValue;
89
90 } // end function setBalance
© 2003 Prentice Hall, Inc.
All rights reserved.
43
1
2
// Fig. 14.12: fig14_12.cpp
// Creating a randomly accessed file.
Outline
3 #include <iostream>
4
fig14_12.cpp
5 using std::cerr;
6 using std::endl;
(1 of 2)
7 using std::ios;
8
9 #include <fstream>
10
11 using std::ofstream;
12
13 #include <cstdlib>
14 #include "clientData.h" // ClientData class definition
15 Open a file for raw writing
16 int main() using an ofstream object
17 { and ios::binary.
18 ofstream outCredit( "[Link]", ios::binary );
19
20 // exit program if ofstream could not open file
21 if ( !outCredit ) {
22 cerr << "File could not be opened." << endl;
23 exit( 1 );
24
25 } // end if
© 2003 Prentice Hall, Inc.
All rights reserved.
44
26
27 // create ClientData with no information
Outline
28 ClientData blankClient; Create a blank object. Use
29 write to output the raw data
fig14_12.cpp
30 // output 100 blank records to file to a file (passing a pointer to
31
(2 of 2)
for ( int i = 0; i < 100; i++ ) the object and its size).
32 [Link](
33 reinterpret_cast< const char * >( &blankClient ),
34 sizeof( ClientData ) );
35
36 return 0;
37
38 } // end main
© 2003 Prentice Hall, Inc.
All rights reserved.
45
14.9 Writing Data Randomly to a
Random-Access File
• Use seekp to write to exact location in file
– Where does the first record begin?
• Byte 0
– The second record?
• Byte 0 + sizeof(object)
– Any record?
• (Recordnum - 1) * sizeof(object)
© 2003 Prentice Hall, Inc. All rights reserved.
46
1
2
// Fig. 14.13: fig14_13.cpp
// Writing to a random access file.
Outline
3 #include <iostream>
4
fig14_13.cpp
5 using std::cerr;
6 using std::endl;
(1 of 4)
7 using std::cout;
8 using std::cin;
9 using std::ios;
10
11 #include <iomanip>
12
13 using std::setw;
14
15 #include <fstream>
16
17 using std::ofstream;
18
19 #include <cstdlib>
20 #include "clientData.h" // ClientData class definition
21
© 2003 Prentice Hall, Inc.
All rights reserved.
47
22 int main()
23 {
Outline
24 int accountNumber;
25 char lastName[ 15 ];
Open file for raw (binary)
fig14_13.cpp
26 char firstName[ 10 ];
27 double balance;
writing. (2 of 4)
28
29 ofstream outCredit( "[Link]", ios::binary );
30
31 // exit program if ofstream cannot open file
32 if ( !outCredit ) {
33 cerr << "File could not be opened." << endl;
34 exit( 1 );
35
36 } // end if
37
38 cout << "Enter account number "
39 << "(1 to 100, 0 to end input)\n? ";
40
Get account number, put into
41 // require user to specify account number
42 ClientData client;
object. It has not yet been
43 cin >> accountNumber; written to file.
44 [Link]( accountNumber );
45
© 2003 Prentice Hall, Inc.
All rights reserved.
48
46
47
// user enters information, which is copied into file
while ( [Link]() > 0 &&
Outline
48 [Link]() <= 100 ) {
49
fig14_13.cpp
50 // user enters last name, first name and balance
51 cout << "Enter lastname, firstname, balance\n? ";
(3 of 4)
52 cin >> setw( 15 ) >> lastName;
53 cin >> setw( 10 ) >> firstName;
54 cin >> balance;
55
56 // set record lastName, firstName and balance values
57 [Link]( lastName );
Position outCredit to the
58 [Link]( firstName ); proper location in the file
59 [Link]( balance ); (based on the account
60 number).
61 // seek position in file of user-specified record
62 [Link]( ( [Link]() - 1 ) *
63 sizeof( ClientData ) ); Write ClientData object to
64 file at specified position.
65 // write user-specified information in file
66 [Link](
67 reinterpret_cast< const char * >( &client ),
68 sizeof( ClientData ) );
69
© 2003 Prentice Hall, Inc.
All rights reserved.
49
70
71
// enable user to specify another account number
cout << "Enter account number\n? ";
Outline
72 cin >> accountNumber;
73 [Link]( accountNumber );
fig14_13.cpp
74
75 } // end while
(4 of 4)
76
77 return 0;
78
79 } // end main
© 2003 Prentice Hall, Inc.
All rights reserved.
50
Enter account number (1 to
? 37
100, 0 to end input)
Outline
Enter lastname, firstname, balance
? Barker Doug 0.00
Notice that accounts can be fig14_13.cpp
Enter account number
? 29 created in any order. output (1 of 1)
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
© 2003 Prentice Hall, Inc.
All rights reserved.
51
14.10 Reading Data Sequentially from a
Random-Access File
• read - similar to write
– Reads raw bytes from file into memory
– [Link]( reinterpret_cast<char *>( &number ),
sizeof( int ) );
• &number: location to store data
• sizeof(int): how many bytes to read
– Do not use inFile >> number with raw bytes
• >> expects char *
• Upcoming program
– Output data from a random-access file
– Go through each record sequentially
• If no data (accountNumber == 0) then skip
© 2003 Prentice Hall, Inc. All rights reserved.
52
1
2
// Fig. 14.14: fig14_14.cpp
// Reading a random access file.
Outline
3 #include <iostream>
4
fig14_14.cpp
5 using std::cout;
6 using std::endl;
(1 of 3)
7 using std::ios;
8 using std::cerr;
9 using std::left;
10 using std::right;
11 using std::fixed;
12 using std::showpoint;
13
14 #include <iomanip>
15
16 using std::setprecision;
17 using std::setw;
18
19 #include <fstream>
20
21 using std::ifstream;
22 using std::ostream;
23
24 #include <cstdlib> // exit protoyype
25 #include "clientData.h" // ClientData class definition
26
© 2003 Prentice Hall, Inc.
All rights reserved.
53
27 void outputLine( ostream&, const ClientData & );
28
Outline
29 int main()
30 {
fig14_14.cpp
31 ifstream inCredit( "[Link]", ios::in );
32
(2 of 3)
33 // exit program if ifstream cannot open file
34 if ( !inCredit ) {
35 cerr << "File could not be opened." << endl;
36 exit( 1 );
37
38 } // end if
39
40 cout << left << setw( 10 ) Read sizeof(ClientData)
<< "Account" << setw( 16 ) bytes and put
41 into11object
<< "Last Name" << setw( ) << client. This may
"First Name" be an empty
<< left
42 << setw( 10 ) << rightrecord.
<< "Balance" << endl;
43
44 ClientData client; // create record
45
46 // read first record from file
47 [Link]( reinterpret_cast< char * >( &client ),
48 sizeof( ClientData ) );
49
© 2003 Prentice Hall, Inc.
All rights reserved.
54
50
51
// read all records from file
while ( inCredit && ![Link]() ) {
Outline
52
53 // display record Loop exits if there is an error fig14_14.cpp
54 if ( [Link]() != 0 ) reading (inCredit == 0) (3 of 3)
55 outputLine( cout, client );
or EOF is found
56
57 // read next from file
([Link]() == 1)
58 [Link]( reinterpret_cast< char * >( &client ),
59 sizeof( ClientData ) );
60
61 } // end while Output non-empty accounts.
62 Note that outputLine takes
63 return 0; an ostream argument. We
64 could easily output to another
65 } // end main file (opened with an
66
ofstream object, which
67 // display single record
68 void outputLine( ostream &output, const
derives from ostream).
ClientData &record )
69 {
70 output << left << setw( 10 ) << [Link]()
71 << setw( 16 ) << [Link]().data()
72 << setw( 11 ) << [Link]().data()
73 << setw( 10 ) << setprecision( 2 ) << right << fixed
74 << showpoint << [Link]() << endl;
75
76 } // end outputLine
© 2003 Prentice Hall, Inc.
All rights reserved.
55
Account
29
Last Name
Brown
First Name
Nancy
Balance
-24.54
Outline
33 Dunn Stacey 314.33
37 Barker Doug 0.00
fig14_14.cpp
88 Smith Dave 258.34
96 Stone Sam 34.98
output (1 of 1)
© 2003 Prentice Hall, Inc.
All rights reserved.
56
14.11 Example: A Transaction-Processing
Program
• Instant access for bank accounts
– Use random access file (data in [Link])
• Give user menu
– Option 1: store accounts to [Link]
Account Last Name First Name Balance
29 Brown Nancy -24.54
33 Dunn Stacey 314.33
37 Barker Doug 0.00
88 Smith Dave 258.34
96 Stone Sam 34.98
– Option 2: update record
Enter account to update (1 - 100): 37
37 Barker Doug 0.00
Enter charge (+) or payment (-): +87.99
37 Barker Doug 87.99
© 2003 Prentice Hall, Inc. All rights reserved.
57
14.11 Example: A Transaction-Processing
Program
• Menu options (continued)
– Option 3: add new record
Enter new account number (1 - 100): 22
Enter lastname, firstname, balance
? Johnston Sarah 247.45
– Option 4: delete record
Enter account to delete (1 - 100): 29
Account #29 deleted.
• To open file for reading and writing
– Use fstream object
– "Or" file-open modes together
fstream inOutCredit( "[Link]", ios::in | ios::out );
© 2003 Prentice Hall, Inc. All rights reserved.
58
1
2
// Fig. 14.15: fig14_15.cpp
// This program reads a random access file sequentially, updates
Outline
3 // data previously written to the file, creates data to be placed
4 // in the file, and deletes data previously in the file.
fig14_15.cpp
5 #include <iostream>
6
(1 of 14)
7 using std::cout;
8 using std::cerr;
9 using std::cin;
10 using std::endl;
11 using std::ios;
12 using std::left;
13 using std::right;
14 using std::fixed;
15 using std::showpoint;
16
17 #include <fstream>
18
19 using std::ofstream;
20 using std::ostream;
21 using std::fstream;
22
23 #include <iomanip>
24
25 using std::setw;
26 using std::setprecision;
27
28 #include <cstdlib> // exit prototype
29 #include "clientData.h" // ClientData class definition
© 2003 Prentice Hall, Inc.
All rights reserved.
59
30
31 int enterChoice();
Outline
32 void printRecord( fstream& );
33 void updateRecord( fstream& );
fig14_15.cpp
34 void newRecord( fstream& );
35 void deleteRecord( fstream& );
(2 of 14)
36 void outputLine( ostream&, const ClientData & );
37 int getAccount( const char * const );
38
39 enum Choices { PRINT = 1, UPDATE, NEW, DELETE, END };
40
41 int main()
Open file for reading and
42 { writing (fstream object
43 // open file for reading and writing needed).
44 fstream inOutCredit( "[Link]", ios::in | ios::out );
45
46 // exit program if fstream cannot open file
47 if ( !inOutCredit ) {
48 cerr << "File could not be opened." << endl;
49 exit ( 1 );
50
51 } // end if
52
© 2003 Prentice Hall, Inc.
All rights reserved.
60
53
54
int choice;
Outline
55 // enable user to specify action
56 while ( ( choice = enterChoice() ) != END ) {
fig14_15.cpp
57
58 switch ( choice ) {
(3 of 14)
59
60 // create text file from record file
61 case PRINT:
62 printRecord( inOutCredit );
63 break;
64
65 // update record
66 case UPDATE:
67 updateRecord( inOutCredit );
68 break;
69
70 // create record
71 case NEW:
72 newRecord( inOutCredit );
73 break;
74
75 // delete existing record
76 case DELETE:
77 deleteRecord( inOutCredit );
78 break;
79
© 2003 Prentice Hall, Inc.
All rights reserved.
61
53
54
int choice;
Outline
55 // enable user to specify action
56 while ( ( choice = enterChoice() ) != END ) {
fig14_15.cpp
57
58 switch ( choice ) { Displays menu and returns (4 of 14)
59 user's choice.
60 // create text file from record file
61 case PRINT:
62 printRecord( inOutCredit );
63 break;
64
65 // update record
66 case UPDATE:
67 updateRecord( inOutCredit );
68 break;
69
70 // create record
71 case NEW:
72 newRecord( inOutCredit );
73 break;
74
75 // delete existing record
76 case DELETE:
77 deleteRecord( inOutCredit );
78 break;
79
© 2003 Prentice Hall, Inc.
All rights reserved.
62
80
81
// display error if user does not select valid choice
default:
Outline
82 cerr << "Incorrect choice" << endl;
83 break;
fig14_15.cpp
84
85 } // end switch
(5 of 14)
86
87 [Link](); // reset end-of-file indicator
88
89 } // end while
90
91 return 0;
92
93 } // end main
94
95 // enable user to input menu choice
96 int enterChoice()
97 {
98 // display available options
99 cout << "\nEnter your choice" << endl
100 << "1 - store a formatted text file of accounts" << endl
101 << " called \"[Link]\" for printing" << endl
102 << "2 - update an account" << endl
103 << "3 - add a new account" << endl
104 << "4 - delete an account" << endl
105 << "5 - end program\n? ";
© 2003 Prentice Hall, Inc.
All rights reserved.
63
106
107 int menuChoice;
Outline
108 cin >> menuChoice; // receive choice from user
109
fig14_15.cpp
110 return menuChoice;
111
(6 of 14)
112 } // end function enterChoice
113
114 // create formatted text file for printing
115 void printRecord( fstream &readFromFile ) Output to [Link]. First,
116 { print the header for the table.
117 // create text file
118 ofstream outPrintFile( "[Link]", ios::out );
119
120 // exit program if ofstream cannot create file
121 if ( !outPrintFile ) {
122 cerr << "File could not be created." << endl;
123 exit( 1 );
124
125 } // end if
126
127 outPrintFile << left << setw( 10 ) << "Account" << setw( 16 )
128 << "Last Name" << setw( 11 ) << "First Name" << right
129 << setw( 10 ) << "Balance" << endl;
130
© 2003 Prentice Hall, Inc.
All rights reserved.
64
131
132
// set file-position pointer to beginning of record file
[Link]( 0 );
Outline
133
134 // read first record from record file Go to front of file, read
fig14_15.cpp
135 ClientData client; account data,(7and print record
136 [Link]( reinterpret_cast< char * >( &client ),
of 14)
if not empty.
137 sizeof( ClientData ) );
138
139 // copy all records from record file into text file Note that outputLine takes
140 while ( ![Link]() ) { an ostream object (base of
141 ofstream). It can easily
142 // write single record to text file print to a file (as in this case)
143 if ( [Link]() != 0 ) or cout.
144 outputLine( outPrintFile, client );
145
146 // read next record from record file
147 [Link]( reinterpret_cast< char * >( &client ),
148 sizeof( ClientData ) );
149
150 } // end while
151
152 } // end function printRecord
153
© 2003 Prentice Hall, Inc.
All rights reserved.
65
154 // update balance in record
155 void updateRecord( fstream &updateFile )
Outline
156 {
157 // obtain number of account to update
fig14_15.cpp
158 int accountNumber = getAccount( "Enter account to update" );
159
(8 of 14)
160 // move file-position pointer to correct record in file
161 [Link]( This is fstream (I/O)
162 ( accountNumber - 1 ) * sizeof(because we must
ClientData ) );read the old
163 balance, update it, and write
164 // read first record from file
the new balance.
165 ClientData client;
166 [Link]( reinterpret_cast< char * >( &client ),
167 sizeof( ClientData ) );
168
169 // update record
170 if ( [Link]() != 0 ) {
171 outputLine( cout, client );
172
173 // request user to specify transaction
174 cout << "\nEnter charge (+) or payment (-): ";
175 double transaction; // charge or payment
176 cin >> transaction;
177
178 // update record balance
179 double oldBalance = [Link]();
180 [Link]( oldBalance + transaction );
181 outputLine( cout, client );
182
© 2003 Prentice Hall, Inc.
All rights reserved.
66
183
184
// move file-position pointer to correct record in file
[Link](
Outline
185 ( accountNumber - 1 ) * sizeof( ClientData ) );
186
fig14_15.cpp
187 // write updated record over old record in file
188 [Link](
(9 of 14)
189 reinterpret_cast< const char * >( &client ),
190 sizeof( ClientData ) );
191
192 } // end if
193
194 // display error if account does not exist
195 else
196 cerr << "Account #" << accountNumberThis is fstream because we
197 read to see if a non-empty
<< " has no information." << endl;
198 record already exists. If not,
199 } // end function updateRecord we write a new record.
200
201 // create and insert record
202 void newRecord( fstream &insertInFile )
203 {
204 // obtain number of account to create
205 int accountNumber = getAccount( "Enter new account number" );
206
207 // move file-position pointer to correct record in file
208 [Link](
209 ( accountNumber - 1 ) * sizeof( ClientData ) );
© 2003 Prentice Hall, Inc.
All rights reserved.
67
210
211 // read record from file
Outline
212 ClientData client;
213 [Link]( reinterpret_cast< char * >( &client ),
fig14_15.cpp
214 sizeof( ClientData ) );
215
(10 of 14)
216 // create record, if record does not previously exist
217 if ( [Link]() == 0 ) {
218
219 char lastName[ 15 ];
220 char firstName[ 10 ];
221 double balance;
222
223 // user enters last name, first name and balance
224 cout << "Enter lastname, firstname, balance\n? ";
225 cin >> setw( 15 ) >> lastName;
226 cin >> setw( 10 ) >> firstName;
227 cin >> balance;
228
229 // use values to populate account values
230 [Link]( lastName );
231 [Link]( firstName );
232 [Link]( balance );
233 [Link]( accountNumber );
234
© 2003 Prentice Hall, Inc.
All rights reserved.
68
235
236
// move file-position pointer to correct record in file
[Link]( ( accountNumber - 1 ) *
Outline
237 sizeof( ClientData ) );
238
fig14_15.cpp
239 // insert record in file
240 [Link](
(11 of 14)
241 reinterpret_cast< const char * >( &client ),
242 sizeof( ClientData ) );
243
244 } // end if
245
246 // display error if account previously exists
247 else
248 cerr << "Account #" << accountNumber
249 << " already contains information." << endl;
250
251 } // end function newRecord
252
© 2003 Prentice Hall, Inc.
All rights reserved.
69
253 // delete an existing record
254 void deleteRecord( fstream &deleteFromFile )
Outline
255 {
256 // obtain number of account to delete
fig14_15.cpp
257 int accountNumber = getAccount( "Enter account to delete" );
258
(12 of 14)
259 // move file-position pointer to correct record in file
260 [Link](
261 ( accountNumber - 1 ) * sizeof( ClientData ) );
fstream because we read to
262
263 // read record from file
check if the account exits. If it
264 ClientData client; does, we write blank data
265 (erase it).
[Link]( reinterpret_cast< char * >( &client ), If it does not exist,
266 sizeof( ClientData ) ); there is no need to delete it.
267
268 // delete record, if record exists in file
269 if ( [Link]() != 0 ) {
270 ClientData blankClient;
271
272 // move file-position pointer to correct record in file
273 [Link]( ( accountNumber - 1 ) *
274 sizeof( ClientData ) );
275
© 2003 Prentice Hall, Inc.
All rights reserved.
70
276
277
// replace existing record with blank record
[Link](
Outline
278 reinterpret_cast< const char * >( &blankClient ),
279 sizeof( ClientData ) );
fig14_15.cpp
280
281 cout << "Account #" << accountNumber << " deleted.\n";
(13 of 14)
282
283 } // end if
284
285 // display error if record does not exist
286 else
287 outputLine
cerr << "Account #" << accountNumber << is very
" is empty.\n";
288 flexible, and can output to any
289 } // end deleteRecord ostream object (such as a
290
file or cout).
291 // display single record
292 void outputLine( ostream &output, const ClientData &record )
293 {
294 output << left << setw( 10 ) << [Link]()
295 << setw( 16 ) << [Link]().data()
296 << setw( 11 ) << [Link]().data()
297 << setw( 10 ) << setprecision( 2 ) << right << fixed
298 << showpoint << [Link]() << endl;
299
300 } // end function outputLine
301
© 2003 Prentice Hall, Inc.
All rights reserved.
71
302
303
// obtain account-number value from user
int getAccount( const char * const prompt )
Outline
304 {
305 int accountNumber;
fig14_15.cpp
306
307 // obtain account-number value
(14 of 14)
308 do {
309 cout << prompt << " (1 - 100): ";
310 cin >> accountNumber;
311
312 } while ( accountNumber < 1 || accountNumber > 100 );
313
314 return accountNumber;
315
316 } // end function getAccount
© 2003 Prentice Hall, Inc.
All rights reserved.
72
14.12 Input/Output of Objects
• I/O of objects
– Chapter 8 (overloaded >>)
– Only object's data transmitted
• Member functions available internally
– When objects stored in file, lose type info (class, etc.)
• Program must know type of object when reading
– One solution
• When writing, output object type code before real object
• When reading, read type code
– Call proper overloaded function (switch)
© 2003 Prentice Hall, Inc. All rights reserved.