Sei sulla pagina 1di 34

17

File Processing
I read part of it all the way
through.
Samuel Goldwyn

I can only assume that a Do


Not File document is led
in a Do Not File le.
Senator Frank Church
Senate Intelligence
Subcommittee Hearing, 1975

A great memory does not


make a philosopher,
any more than a dictionary
can be called grammar.
John Henry, Cardinal
Newman

OBJECTIVES
In this chapter you will learn:

To create, read, write and update les.

Sequential le processing.

Random-access le processing.

To use high-performance unformatted I/O operations.

The differences between formatted-data and raw-data


le processing.
To build a transaction-processing program using
random-access le processing.

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Chapter 17 File Processing

Self-Review Exercises
17.1

Fill in the blanks in each of the following:


a) Ultimately, all data items processed by a computer are reduced to combinations of
and
.
ANS: 1s, 0s.

b) The smallest data item a computer can process is called a


ANS: bit.

c) A(n)

ANS: file.

is a group of related records.

d) Digits, letters and special symbols are referred to as


.
ANS: characters.
e) A group of related files is called a(n)
.
ANS: database.
f) Member function
of the file streams fstream, ifstream and ofstream closes a file.
ANS: close.

g) The istream member function


ANS: get.

h) Member function
opens a file.
ANS: open.

reads a character from the specified stream.


of the file streams

i) The istream member function


a file in random-access applications.

fstream, ifstream

and

ofstream

is normally used when reading data from

ANS: read.

j) Member functions
and
of istream and ostream, set the fileposition pointer to a specific location in an input or output stream, respectively.
ANS: seekg, seekp.

17.2

State which of the following are true and which are false. If false, explain why.
a) Member function read cannot be used to read data from the input object cin.
ANS: False. Function read can read from any input stream object derived from istream.
b) The programmer must create the cin, cout, cerr and clog objects explicitly.
ANS: False. These four streams are created automatically for the programmer. The <iostream> header must be included in a file to use them. This header includes declarations for each stream object.
c) A program must call function close explicitly to close a file associated with an ifstream,
ofstream or fstream object.
ANS: False. The files will be closed when destructors for ifstream, ofstream or fstream
objects execute when the stream objects go out of scope or before program execution
terminates, but it is a good programming practice to close all files explicitly with
close once they are no longer needed.
d) If the file-position pointer points to a location in a sequential file other than the beginning
of the file, the file must be closed and reopened to read from the beginning of the file.
ANS: False. Member function seekp or seekg can be used to reposition the put or get fileposition pointer to the beginning of the file.
e) The ostream member function write can write to standard-output stream cout.
ANS: True.

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Self-Review Exercises

f) Data in sequential files always is updated without overwriting nearby data.

ANS: False. In most cases, sequential file records are not of uniform length. Therefore, it is

possible that updating a record will cause other data to be overwritten.


g) Searching all records in a random-access file to find a specific record is unnecessary.
ANS: True.
h) Records in random-access files must be of uniform length.
ANS: False. Records in a random-access file normally are of uniform length.
i) Member functions seekp and seekg must seek relative to the beginning of a file.
ANS: False. It is possible to seek from the beginning of the file, from the end of the file and
from the current position in the file.
17.3

Assume that each of the following statements applies to the same program.
a) Write a statement that opens file oldmast.dat for input; use an ifstream object called
inOldMaster.
ANS: ifstream inOldMaster( "oldmast.dat", ios::in );

b) Write a statement that opens file


inTransaction.

trans.dat

for input; use an

ifstream

object called

ANS: ifstream inTransaction( "trans.dat", ios::in );

c) Write a statement that opens file newmast.dat for output (and creation); use ofstream
object outNewMaster.
ANS: ofstream outNewMaster( "newmast.dat", ios::out );

d) Write a statement that reads a record from the file oldmast.dat. The record consists of
integer accountNumber, string name and floating-point currentBalance; use ifstream
object inOldMaster.
ANS: inOldMaster >> accountNumber >> name >> currentBalance;

e) Write a statement that reads a record from the file trans.dat. The record consists of integer accountNum and floating-point dollarAmount; use ifstream object inTransaction.

ANS: inTransaction >> accountNum >> dollarAmount;

f) Write a statement that writes a record to the file newmast.dat. The record consists of
integer accountNum, string name, and floating-point currentBalance; use ofstream object outNewMaster.

ANS: outNewMaster << accountNum << name << currentBalance;

17.4

Find the error(s) and show how to correct it (them) in each of the following.
a) File payables.dat referred to by ofstream object outPayable has not been opened.
outPayable << account << company << amount << endl;

ANS: Error: The file payables.dat has not been opened before the attempt is made to out-

put data to the stream.


Correction: Use ostream function open to open payables.dat for output.
b) The following statement should read a record from the file payables.dat. The ifstream object inPayable refers to this file, and istream object inReceivable refers to
the file receivables.dat.
inReceivable >> account >> company >> amount;

ANS: Error: The incorrect istream object is being used to read a record from the file named
payables.dat.

Correction: Use istream object inPayable to refer to payables.dat.


c) The file tools.dat should be opened to add data to the file without discarding the current data.

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Chapter 17 File Processing


ofstream outTools( "tools.dat", ios::out );

ANS: Error: The files contents are discarded because the file is opened for output

(ios::out).
Correction: To add data to the file, open the file either for updating (ios::ate) or
for appending (ios::app).

Exercise Solutions
17.5

Fill in the blanks in each of the following:


a) Computers store large amounts of data on secondary storage devices as
.
ANS: files.
b) A(n)
is composed of several fields.
ANS: record.
c) To facilitate the retrieval of specific records from a file, one field in each record is chosen
as a
.
ANS: key.
d) The vast majority of information stored in computer systems is stored in
files.
ANS: sequential.
e) A group of related characters that conveys meaning is called a(n)
.
ANS: field.
f) The standard stream objects declared by header <iostream> are
,
,
and
.
ANS: cin, cout, cerr, clog.
g) ostream member function
outputs a character to the specified stream.
ANS: put.
h) ostream member function
is generally used to write data to a randomly accessed file.
ANS: write.
i) istream member function
repositions the file-position pointer in a file.
ANS: seekg.

17.6

State which of the following are true and which are false. If false, explain why.
a) The impressive functions performed by computers essentially involve the manipulation
of zeros and ones.
ANS: True.
b) People prefer to manipulate bits instead of characters and fields because bits are more
compact.
ANS: False. People prefer to manipulate characters and fields because they are less cumbersome and more understandable.
c) People specify programs and data items as characters; computers then manipulate and
process these characters as groups of zeros and ones.
ANS: True.
d) A persons 5-digit zip code is an example of a numeric field.
ANS: True.
e) A persons street address is generally considered to be an alphabetic field in computer
applications.
ANS: False. A street address is generally considered to be alphanumeric field.

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Exercise Solutions

f) Data items represented in computers form a data hierarchy in which data items become
larger and more complex as we progress from fields to characters to bits, etc.
ANS: False. Data items processed by a computer form a data hierarchy in which data items
become larger and more complex as we progress from bits to characters to fields, etc.
g) A record key identifies a record as belonging to a particular field.
ANS: False. A record key identifies a record as belonging to a particular person or entity.
h) Most organizations store all information in a single file to facilitate computer processing.
ANS: False. Most organizations have many files in which they store their information.
i) When a program creates a file, the file is automatically retained by the computer for future reference; i.e., files are said to be persistent.
ANS: True.
17.7 Exercise 17.3 asked the reader to write a series of single statements. Actually, these statements form the core of an important type of file-processing program, namely, a file-matching program. In commercial data processing, it is common to have several files in each application system.
In an accounts-receivable system, for example, there is generally a master file containing detailed information about each customer, such as the customers name, address, telephone number, outstanding balance, credit limit, discount terms, contract arrangements and, possibly, a condensed history
of recent purchases and cash payments.
As transactions occur (e.g., sales are made and cash payments arrive), they are entered into a
le. At the end of each business period (a month for some companies, a week for others and a day
in some cases), the le of transactions (called trans.dat in Exercise 17.3) is applied to the master
le (called oldmast.dat in Exercise 17.3), thus updating each account's record of purchases and
payments. During an updating run, the master le is rewritten as a new le (newmast.dat), which
is then used at the end of the next business period to begin the updating process again.
File-matching programs must deal with certain problems that do not exist in single-le programs. For example, a match does not always occur. A customer on the master le might not have
made any purchases or cash payments in the current business period, and therefore no record for
this customer will appear on the transaction le. Similarly, a customer who did make some purchases or cash payments may have just moved to this community, and the company may not have
had a chance to create a master record for this customer.
Use the statements from Exercise 17.3 as a basis for writing a complete le-matching
accounts-receivable program. Use the account number on each le as the record key for matching
purposes. Assume that each le is a sequential le with records stored in increasing order by
account number.
When a match occurs (i.e., records with the same account number appear on both the master
and transaction les), add the dollar amount on the transaction le to the current balance on the
master le, and write the newmast.dat record. (Assume purchases are indicated by positive
amounts on the transaction le and payments are indicated by negative amounts.) When there is a
master record for a particular account but no corresponding transaction record, merely write the
master record to newmast.dat. When there is a transaction record but no corresponding master
record, print the error message "Unmatched transaction record for account number ..." (ll in
the account number from the transaction record).
ANS:

1
2
3
4
5

// Exercise 17.7 Solution: ex17_07.cpp


#include <iostream>
using std::cerr;
using std::cout;
using std::fixed;

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

6
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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
56
57
58
59

Chapter 17 File Processing

using std::showpoint;
#include <iomanip>
using std::setprecision;
#include <fstream>
using std::ofstream;
using std::ifstream;
#include <string>
using std::string;
#include <cstdlib> // exit function prototype
using std::exit;
void printOutput( ofstream&, int, string, string, double ); // prototype
int main()
{
int masterAccount; // holds account from old master file
int transactionAccount; // holds account from transactions file
double masterBalance; // holds balance from old master file
double transactionBalance; // holds balance from transactions file
char masterFirstName[ 20 ]; // first name from master file
char masterLastName[ 20 ]; // last name from master file
// file streams for input and output files
ifstream inOldMaster( "oldmast.dat" );
ifstream inTransaction( "trans.dat" );
ofstream outNewMaster( "newmast.dat" );
// terminate application if old master file cannot be opened
if ( !inOldMaster )
{
cerr << "Unable to open oldmast.dat\n";
exit( 1 );
} // end if
// terminate application if transactions file cannot be opened
if ( !inTransaction )
{
cerr << "Unable to open trans.dat\n";
exit( 1 );
} // end if
// terminate application if new master file cannot be opened
if ( !outNewMaster )
{
cerr << "Unable to open newmast.dat\n";
exit( 1 );
} // end if
// display account currently being processed
cout << "Processing...\n";

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Exercise Solutions
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113

inTransaction >> transactionAccount >> transactionBalance;


// read from master file until end of transactions file reached
while ( !inTransaction.eof() )
{
inOldMaster >> masterAccount >> masterFirstName
>> masterLastName >> masterBalance;
// display accounts from master file until
// number of new account is reached
while ( masterAccount < transactionAccount && !inOldMaster.eof() )
{
printOutput( outNewMaster, masterAccount, masterFirstName,
masterLastName, masterBalance );
inOldMaster >> masterAccount >> masterFirstName
>> masterLastName >> masterBalance;
} // end while
// tell user if account from transactions file does not match
// account from master file
if ( masterAccount > transactionAccount )
{
cout << "Unmatched transaction record for account "
<< transactionAccount << '\n';
// get account and balance from transactions file
inTransaction >> transactionAccount >> transactionBalance;
} // end if
// if matching account found, update balance and output account info
if ( masterAccount == transactionAccount )
{
masterBalance += transactionBalance;
printOutput( outNewMaster, masterAccount, masterFirstName,
masterLastName, masterBalance );
} // end if
// get next account and balance from transactions file
inTransaction >> transactionAccount >> transactionBalance;
} // end while
// output remaining accounts to new master file
while ( !inOldMaster.eof() )
{
inOldMaster >> masterAccount >> masterFirstName
>> masterLastName >> masterBalance;
printOutput( outNewMaster, masterAccount, masterFirstName,
masterLastName, masterBalance );
} // end while
inTransaction.close(); // close transactions file
outNewMaster.close(); // close new master file
inOldMaster.close(); // close old master file
return 0;

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

8
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129

Chapter 17 File Processing

} // end main
// function to display output
void printOutput( ofstream &oRef, int mAccount, string mfName,
string mlName, double mBalance )
{
// set output format
cout << fixed << showpoint;
oRef << fixed << showpoint;
// display account number,
oRef << mAccount << ' ' <<
<< setprecision( 2 ) <<
cout << mAccount << ' ' <<
<< setprecision( 2 ) <<
} // end function printOutput

name and balance


mfName << ' ' << mlName << ' '
mBalance << '\n';
mfName << ' ' << mlName << ' '
mBalance << '\n';

Processing...
100 Ajax Orange 678.06
300 Sue Green 650.07
400 Clint White 994.22
Unmatched transaction record for account 445
500 Aias Blue 895.80
700 Tom Black -23.57
900 Marisal Pink 200.55

Contents of oldmast.dat
100
300
400
500
700
900

Ajax Orange 543.89


Sue Green 22.88
Clint White -6.32
Aias Blue 888.71
Tom Black 76.09
Marisal Pink 100.55

Contents of trans.dat
100
300
400
445
500
700
900

134.17
627.19
1000.54
55.55
7.09
-99.66
100.00

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Exercise Solutions

Contents of newmast.dat
100
300
400
500
700
900

Ajax Orange 678.06


Sue Green 650.07
Clint White 994.22
Aias Blue 895.80
Tom Black -23.57
Marisal Pink 200.55

17.8 After writing the program of Exercise 17.7, write a simple program to create some test data
for checking out the program. Use the following sample account data:

Master le
Account number

Name

Balance

100

Alan Jones

348.17

300

Mary Smith

27.19

500

Sam Sharp

0.00

700

Suzy Green

14.22

Transaction le
Account
number

Transaction amount

100

27.14

300

62.11

400

100.56

900

82.17

ANS:

1
2
3
4
5
6
7
8
9
10
11
12

// Exercise 17.8 Solution: ex17_08.cpp


#include <iostream>
using std::cerr;
using std::cout;
#include <iomanip>
using std::fixed;
using std::setprecision;
using std::showpoint;
#include <fstream>
using std::ofstream;

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

10
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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
56
57
58
59
60
61
62
63
64
65
66

Chapter 17 File Processing

using std::ifstream;
#include <string>
using std::string;
#include <cstdlib>
using std::exit;
using std::rand;
using std::srand;
#include <ctime>
using std::time;
int main()
{
// account number
const int accountNumbers[] = { 100, 300, 500, 700 };
// names of account holders
const string names[] = { "Alan Jones", "Mary Smith", "Sam Sharp",
"Suzy Green" };
// balances of account holders
const double balances[] = { 348.17, 27.19, 0.00, -14.22 };
// account transactions
const double transactionAmounts[] = { 27.14, 62.11, 100.56, 82.17 };
// intialize output streams and open output files
ofstream outOldMaster( "oldMast.dat" );
ofstream outTransaction( "trans.dat" );
int z; // used for loop counting
// terminate program if master output file cannot be opened
if ( !outOldMaster )
{
cerr << "Unable to open oldmast.dat\n";
exit( 1 );
} // end if
// terminate application if output transactions file cannot be opened
if ( !outTransaction )
{
cerr << "Unable to open trans.dat\n";
exit( 1 );
} // end if
// write data to "oldmast.dat"
cout << fixed << showpoint << "Contents of \"oldmast.dat\":\n";
// create random master account balances and write to file
outOldMaster << fixed << showpoint;

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Exercise Solutions
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91

for ( z = 0; z < 4; z++ )


{
outOldMaster << accountNumbers[ z ] << ' ' << names[ z ] << ' '
<< setprecision( 2 ) << balances[ z ] << '\n';
cout << accountNumbers[ z ] << ' ' << names[ z ] << ' '
<< setprecision( 2 ) << balances[ z ] << '\n';
} // end for
// write data to "trans.dat"
cout << "\nContents of \"trans.dat\":\n";
outTransaction << fixed << showpoint;
// create random transactions and write to file
for ( z = 0; z < 4; z++ )
{
outTransaction << accountNumbers[ z ] << ' ' << setprecision( 2 )
<< transactionAmounts[ z ] << '\n';
cout << accountNumbers[ z ] << ' ' << setprecision( 2 )
<< transactionAmounts[ z ] << '\n';
} // end for
outTransaction.close(); // close transactions file
outOldMaster.close(); // close master file
return 0;
} // end main

Contents of "oldmast.dat":
100 Alan Jones 348.17
300 Mary Smith 27.19
500 Sam Sharp 0.00
700 Suzy Green -14.22
Contents of "trans.dat":
100 27.14
300 62.11
500 100.56
700 82.17

Contents of oldMast.dat
100
300
500
700

11

Alan Jones 348.17


Mary Smith 27.19
Sam Sharp 0.00
Suzy Green -14.22

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

12

Chapter 17 File Processing


Contents of trans.dat

100
300
500
700

27.14
62.11
100.56
82.17

17.9 Run the program of Exercise 17.7, using the files of test data created in Exercise 17.8. Print
the new master file. Check that the accounts have been updated correctly.
ANS: Contents of newmast.dat
100
300
500
700

Alan Jones 375.31


Mary Smith 89.30
Sam Sharp 100.56
Suzy Green 67.95

17.10 It is possible (actually common) to have several transaction records with the same record
key. This occurs because a particular customer might make several purchases and cash payments
during a business period. Rewrite your accounts-receivable file-matching program of Exercise 17.7
to provide for the possibility of handling several transaction records with the same record key. Modify the test data of Exercise 17.8 to include the following additional transaction records:

Account number

Dollar amount

300

83.89

700

80.78

700

1.53

ANS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14

// Exercise 17.10 Solution: ex17_10.cpp


#include <iostream>
using std::cerr;
using std::cout;
#include <fstream>
using std::ifstream;
using std::ofstream;
#include <iomanip>
using std::setprecision;
using std::fixed;
using std::showpoint;

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Exercise Solutions
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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
56
57
58
59
60
61
62
63
64
65
66
67
68

13

#include <string>
using std::string;
#include <cstdlib>
using std::exit;
void printOutput( ofstream &, int, string, string, double );
int main()
{
// variables hold account information from input files
int masterAccount;
int transactionAccount;
double masterBalance;
double transactionBalance;
char masterFirstName[ 20 ];
char masterLastName[ 20 ];
// create file streams and open files
ifstream inOldmaster( "oldmast.dat" );
ifstream inTransaction( "trans.dat" );
ofstream outNewmaster( "newmast.dat" );
// terminate program if input master file cannot be opened
if ( !inOldmaster )
{
cerr << "Unable to open oldmast.dat\n";
exit( 1 );
} // end if
// terminate program if input transaction file cannot be opened
if ( !inTransaction )
{
cerr << "Unable to open trans.dat\n";
exit( 1 );
} // end if
// terminate program if output master file cannot be opened
if ( !outNewmaster )
{
cerr << "Unable to open newmast.dat\n";
exit( 1 );
} // end file
cout << "Processing....\n";
// get first transaction from input file
inTransaction >> transactionAccount >> transactionBalance;
// continue until end of transaction file is reached
while ( !inTransaction.eof() )
{
// get account information from input master file
inOldmaster >> masterAccount >> masterFirstName >> masterLastName

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

14
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122

Chapter 17 File Processing

>> masterBalance;
// write master accounts to output master file until first account
// that made a transaction is reached
while ( masterAccount < transactionAccount && !inOldmaster.eof() )
{
printOutput( outNewmaster, masterAccount, masterFirstName,
masterLastName, masterBalance );
inOldmaster >> masterAccount >> masterFirstName >> masterLastName
>> masterBalance;
} // end inner while
// if transaction account does not have a matching input file
// inform user get next transaction information
if ( masterAccount > transactionAccount )
{
cout << "Unmatched transaction record for account "
<< transactionAccount << '\n';
inTransaction >> transactionAccount >> transactionBalance;
} // end if
// if transaction account does not have a matching input file
// inform user get next transaction information
else if ( masterAccount < transactionAccount )
{
cout << "Unmatched transaction record for account "
<< transactionAccount << '\n';
inTransaction >> transactionAccount >> transactionBalance;
} // end if
// process all transactions made by a master account holder
while ( masterAccount == transactionAccount &&
!inTransaction.eof() )
{
masterBalance += transactionBalance;
inTransaction >> transactionAccount >> transactionBalance;
} // end inner while
// display account information
printOutput( outNewmaster, masterAccount, masterFirstName,
masterLastName, masterBalance );
} // end outer while
// output remaining accounts to new master file
while ( !inOldmaster.eof() )
{
inOldmaster >> masterAccount >> masterFirstName
>> masterLastName >> masterBalance;
printOutput( outNewmaster, masterAccount, masterFirstName,
masterLastName, masterBalance );
} // end while
inTransaction.close(); // close transaction input file
outNewmaster.close(); // close master output file

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Exercise Solutions
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139

inOldmaster.close(); // close master input file


return 0;
} // end main
// function to display account information
void printOutput( ofstream &oRef, int mAccount, string mfName,
string mlName, double mBalance )
{
// set output formats and display account information
cout << showpoint << fixed;
oRef << showpoint << fixed;
oRef << mAccount << ' ' << mfName << ' ' << mlName << ' '
<< setprecision( 2 ) << mBalance << '\n';
cout << mAccount << ' ' << mfName << ' ' << mlName << ' '
<< setprecision( 2 ) << mBalance << '\n';
cout << showpoint << fixed;
} // end function printOutput

Processing....
100 Alan Jones 375.31
300 Mary Smith 173.19
500 Sam Sharp 100.56
700 Suzy Green 150.26

Contents of oldmast.dat
100
300
500
700

Alan Jones 348.17


Mary Smith 27.19
Sam Sharp 0.00
Suzy Green -14.22

Contents of trans.dat
100
300
300
500
700
700
700

27.14
62.11
83.89
100.56
82.17
80.78
1.53

Contents of newmast.dat
100
300
500
700

Alan Jones 375.31


Mary Smith 173.19
Sam Sharp 100.56
Suzy Green 150.26

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

15

16

Chapter 17 File Processing

17.11 Write a series of statements that accomplish each of the following. Assume that we have defined class Person that contains private data members
char lastName[ 15 ];
char firstName[ 15 ];
char age[ 4 ];
int id;

and public member functions


// accessor functions for id
void setId( int );
int getId() const;
// accessor functions for lastName
void setLastName( string );
string getLastName() const;
// accessor functions for firstName
void setFirstName( string );
string getFirstName() const;
// accessor functions for age
void setAge( string );
string getAge() const;

Also assume that any random-access les have been opened properly.
a) Initialize the file nameage.dat with 100 records that store values
"unassigned", firstName = "" and age = "0".

id = 0, lastName =

ANS:
// fstream object "fileObject" corresponds to file nameage.dat
Person blankPerson();
blankPerson.setLastName( "unassigned" );
blankPerson.setFirstName( "" );
blankPerson.setAge( "0" );
blankPerson.id = 0;
for ( int r = 0; r < 100; r++ )
fileObject.write( reinterpret_cast< const char * >( &blankPerson ),
sizeof( Person ) );

b) Input 10 last names, first names, ages, and ids and write them to the file.
ANS:
string last;
string first;
string age;
int id;
int counter = 1;
while ( counter <= 10 )
{
do // obtain id-number value
{
cout << "Enter id number for new record (1 - 100): "
cin << id;
} while ( ( id < 1 ) || ( id > 100 ) );
// move file-position pointer to correct record in file

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Exercise Solutions

17

fileObject.seekg( ( id - 1 ) * sizeof( Person ) );


// read record from file to determine if one already exists
Person person;
fileObject.read( reinterpret_cast< char * >( &person ),
sizeof( Person ) );
// create record, if record does not previously exist
if ( person.getId() == 0 )
{
cout << "Enter last name, first name, and age: ";
cin >> setw( 15 ) last;
cin >> setw( 15 ) first;
cin >> setw( 4 ) >> age;
person.setLastName( last );
person.setFirstName( first );
person.setAge( age )
person.setId( id );
// move file-position pointer to correct record in file
fileObject.seekp( ( id - 1 ) * sizeof( Person ) );
// insert new record
fileObject.write(
reinterpret_cast< const char * >( &person ), sizeof( Person ) );
counter++; // record added, increase counter
} // end if
else // display error if record previously exists
cerr << "Record #" << id << " already contains data." << endl;
} // end while

c) Update a record that already contains information. If the record does not contain information, inform the user "No info".
ANS:
string last;
string first;
string age;
int id;
do // obtain id-number value
{
cout << "Enter id number for new record (1 - 100): "
cin << id;
} while ( ( id < 1 ) || ( id > 100 ) );
// move file-position pointer to correct record in file
fileObject.seekg( ( id - 1 ) * sizeof( Person ) );
// read record from file to determine if one already exists
Person person;
fileObject.read( reinterpret_cast< char * >( &person ),
sizeof( Person ) );
// update record, if no record currently exists
if ( person.getId() != 0 )
{
cout << "Enter new last name, first name, and age: ";
cin >> setw( 15 ) last;
cin >> setw( 15 ) first;

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

18

Chapter 17 File Processing


cin >> setw( 4 ) >> age;
person.setLastName( last );
person.setFirstName( first );
person.setAge( age )
person.setId( id );
// move file-position pointer to correct record in file
fileObject.seekp( ( id - 1 ) * sizeof( Person ) );
// insert new record
fileObject.write(
reinterpret_cast< const char * >( &person ), sizeof( Person ) );
} // end if
else // display error if record did not previously exists
cerr << "No info." << endl;

d) Delete a record that contains information by reinitializing that particular record.


ANS:
do // obtain id-number value
{
cout << "Enter id number for new record (1 - 100): "
cin << id;
} while ( ( id < 1 ) || ( id > 100 ) );
// move file-position pointer to correct record in file
fileObject.seekg( ( id - 1 ) * sizeof( Person ) );
// read record from file
Person person;
fileObject.read( reinterpret_cast< char * >( &person ),
sizeof( Person ) );
if ( person.id != 0 ) // delete record, if record exists in file
{
// create blank record
Person blankPerson();
blankPerson.setLastName( "unassigned" );
blankPerson.setFirstName( "" );
blankPerson.setAge( "0" );
blankPerson.id = 0;
// move file-position pointer to correct record in file
fileObject.seekp( ( id - 1 ) * sizeof( Person ) );
// replace existing record with blank record
fileObject.write( reinterpret_cast< const char * >( &blankPerson ),
sizeof( Person ) );
cout << "Record #" << id << " deleted." << endl;
} // end if
else // display error if record does not exist
cerr << "Record #" << id << " is empty." << endl;

17.12 You are the owner of a hardware store and need to keep an inventory that can tell you what
different tools you have, how many of each you have on hand and the cost of each one. Write a
program that initializes the random-access file hardware.dat to 100 empty records, lets you input
the data concerning each tool, enables you to list all your tools, lets you delete a record for a tool
that you no longer have and lets you update any information in the file. The tool identification
number should be the record number. Use the following information to start your file:
2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Exercise Solutions

Record #

Tool name

Quantity

Cost

Electric sander

57.98

17

Hammer

76

11.99

24

Jig saw

21

11.00

39

Lawn mower

79.50

56

Power saw

18

99.99

68

Screwdriver

106

6.99

77

Sledge hammer

11

21.50

83

Wrench

34

7.50

ANS:

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
30
31
32
33
34

// Exercise 17.12 Solution: Tool.h


// Class Tool definition for hardware store program.
#ifndef TOOL_H
#define TOOL_H
#include <string>
using std::string;
const int LENGTH = 30; // length of tool name
class Tool
{
public:
// default Tool constructor
Tool( int = -1, string = "", int = 0, double = 0.0 );
// accessor functions for partNumber
void setPartNumber( int );
int getPartNumber() const;
// accessor functions for toolName
void setToolName( string );
string getToolName() const;
// accessor functions for inStock
void setInStock( int );
int getInStock() const;
// accessor functions for unitPrice
void setUnitPrice( double );
double getUnitPrice() const;
private:
int partNumber; // part id number
char toolName[ LENGTH ]; // tool name

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

19

20

Chapter 17 File Processing

35
36
37
38
39

int inStock; // number in stock


double unitPrice; // price per unit
}; // end class Tool

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

// Exercise 17.12 Solution: Tool.cpp


// Member function definitions for class Tool.
#include <string>
using std::string;

#endif

#include <cstring>
using std::strncpy;
#include "Tool.h"
// default Tool constructor
Tool::Tool( int partNumberValue, string toolNameValue, int inStockValue,
double unitPriceValue )
{
setPartNumber( partNumberValue );
setToolName( toolNameValue );
setInStock( inStockValue );
setUnitPrice( unitPriceValue );
} // end Tool constructor
// set part-number value
void Tool::setPartNumber( int partNumberValue )
{
partNumber = partNumberValue;
} // end function setPartNumber
// get part-number value
int Tool::getPartNumber() const
{
return partNumber;
} // end function getPartNumber
// set tool-name value
void Tool::setToolName( string toolNameString )
{
// copy at most 30 characters from string to toolName
const char *toolNameValue = toolNameString.data();
int length = toolNameString.size();
length = ( length < 30 ? length : 29 );
strncpy( toolName, toolNameValue, length );
// append null-terminating character to end of toolName
toolName[ length ] = '\0';
} // end function setToolName
// get tool-name value
string Tool::getToolName() const

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Exercise Solutions
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74

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

// Exercise 17.12 Solution: ex17_12.cpp


#include <iostream>
using std::cerr;
using std::cin;
using std::cout;
using std::endl;
using std::ios;

return toolName;
} // end function getToolName
// set in-stock value
void Tool::setInStock( int inStockValue )
{
inStock = inStockValue;
} // end function setInStock
// get in-stock value
int Tool::getInStock() const
{
return inStock;
} // end function getInStock
// set unit-price value
void Tool::setUnitPrice( double unitPriceValue )
{
unitPrice = unitPriceValue;
} // end function setUnitPrice
// get unit-price value
double Tool::getUnitPrice() const
{
return unitPrice;
} // end function getUnitPrice

#include <iomanip>
using std::fixed;
using std::left;
using std::setprecision;
using std::setw;
using std::showpoint;
#include <fstream>
using std::fstream;
#include <cctype>
using std::toupper;
#include <cstdlib>
using std::exit;
#include "Tool.h"

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

21

22
26
27
28
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79

Chapter 17 File Processing

// function prototypes
void initializeFile( fstream
void inputData( fstream & );
void listTools( fstream & );
void updateRecord( fstream &
void insertRecord( fstream &
void deleteRecord( fstream &
int instructions( void );

& );
);
);
);

int main()
{
int choice;
char response;
// file stream used for input and output
fstream file( "hardware.dat", ios::in | ios::out );
void ( *f[] )( fstream & ) =
{ listTools, updateRecord, insertRecord, deleteRecord };
// terminate program if file cannot be opened
if ( !file )
{
cerr << "File could not be opened.\n";
exit( 1 );
} // end if
// ask user if new file should be made
cout << "Should the file be initialized (Y or N): ";
cin >> response;
response = toupper( response );
// test if user's response was valid
while ( ( response != 'Y' ) && ( response != 'N' ) )
{
cout << "Invalid response. Enter Y or N: ";
cin >> response;
response = toupper( response );
} // end while
// initialize file if user says to
if ( response == 'Y' )
{
initializeFile( file );
inputData( file );
} // end if
// perform user instructions until 5 is entered
while ( ( choice = instructions() ) != 5 )
{
( *f[ choice - 1 ] )( file );
file.clear(); // reset eof indicator
} // end while

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Exercise Solutions
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133

23

file.close(); // close input/output file


return 0;
} // end main
// function to clear file
void initializeFile( fstream &fRef )
{
Tool blankItem; // empty Tool object
// fill file with blank records
for ( int i = 0; i < 100; i++ )
fRef.write(
reinterpret_cast< char * >( &blankItem ), sizeof( Tool ) );
} // end function initializeFile
// function that receives input
void inputData( fstream &fRef )
{
Tool temp; // temporary Tool object
// temporary variables used to hold user input
int number;
char name[ LENGTH ];
double price;
int stock;
// ask user for and set partNumber
cout << "Enter the part number (0 - 99, -1 to end input): ";
cin >> number;
// set Tool members until -1 is entered
while ( number != -1 )
{
cout << "Enter the tool name: "; // ask user for tool name
cin.ignore(); // ignore the newline on the input stream
cin.get( name, LENGTH ); // store tool name in variable name
temp.setToolName( name ); // set tool member name
temp.setPartNumber( number ); // set part number
// ask user for quantity and price
cout << "Enter quantity and price: ";
cin >> stock >> price; // store input in temporary variables
temp.setInStock( stock ); // set inStock
temp.setUnitPrice( price ); // set unitPrice
// place file position pointer at next write location
fRef.seekp( ( temp.getPartNumber() ) * sizeof( Tool ) );
// write data to file
fRef.write( reinterpret_cast< char * >( &temp ), sizeof( Tool ) );
// ask user for next part number
cout << "Enter the part number (0 - 99, -1 to end input): ";
cin >> number;

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

24
134
135
136
137
138
139
140
141
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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187

Chapter 17 File Processing

} // end while
} // end inputData
// function that decides what choice user selected
int instructions()
{
int choice;
// ask user to enter a choice
cout << "\nEnter a choice:\n1
<< "\n2 Update record.\n3
<< "\n4 Delete record.\n5

List all tools."


Insert record."
End program.\n";

// ask user for choice until a valid choice is entered


do
{
cout << "? ";
cin >> choice;
} while ( choice < 1 || choice > 5 );
return choice; // return user choice
} // end function instructions
// function that lists tools in file
void listTools( fstream &fRef )
{
Tool temp;
// display column headings
cout << setw( 7 ) << "Record#" << "
" << left
<< setw( 30 ) << "Tool name" << left
<< setw( 13 ) << "Quantity" << left << setw( 10 ) << "Cost" << endl;
// continue until 100 tools are displayed or end of file reached
for ( int count = 0; count < 100 && !fRef.eof(); count++ )
{
// set file position pointer and begin reading
fRef.seekg( count * sizeof( Tool ) );
fRef.read( reinterpret_cast< char * >( &temp ), sizeof( Tool ) );
// if part number is valid, display Tool information
if ( temp.getPartNumber() >= 0 && temp.getPartNumber() < 100 )
{
cout << fixed << showpoint;
cout << left << setw( 7 ) << temp.getPartNumber() << "
"
<< left << setw( 30 ) << temp.getToolName() << left
<< setw( 13 ) << temp.getInStock() << setprecision( 2 )
<< left << setw( 10 ) << temp.getUnitPrice() << '\n';
} // end if
} // end for
} // end function listTools
// function to update a tool's information
void updateRecord( fstream &fRef )

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Exercise Solutions
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241

25

Tool temp;
int part;
char name[ LENGTH ];
int stock;
double price;
// ask user what part to update
cout << "Enter the part number for update: ";
cin >> part;
// set file position pointer to correct tool
fRef.seekg( part * sizeof( Tool ) );
// read tool information
fRef.read( reinterpret_cast< char * >( &temp ), sizeof( Tool ) );
// display tool information if partNumber is not -1
if ( temp.getPartNumber() != -1 )
{
cout << setw( 7 ) << "Record#" << "
" << left
<< setw( 30 ) << "Tool name" << left
<< setw( 13 ) << "Quantity" << setw( 10 ) << "Cost" << endl;
cout << fixed << showpoint;
cout << setw( 7 ) << temp.getPartNumber() << "
"
<< left << setw( 30 ) << temp.getToolName()
<< left << setw( 13 ) << temp.getInStock()
<< setprecision( 2 ) << setw( 10 ) << temp.getUnitPrice() << '\n'
<< "Enter the tool name: "; // ask user for new name
cin.ignore(); // ignore the newline on the input stream
cin.get( name, LENGTH ); // set new name
temp.setToolName( name );
cout << "Enter quantity and price: "; // ask for price and quantity
cin >> stock >> price;
temp.setInStock( stock ); // set new quantity
temp.setUnitPrice( price ); // get new price

// set file position pointer and write information to file


fRef.seekp( ( temp.getPartNumber() ) * sizeof( Tool ) );
fRef.write( reinterpret_cast< char * > ( &temp ), sizeof( Tool ) );
} // end if
else
cerr << "Cannot update. The record is empty.\n";
} // end function updateRecord
// function to insert a new record
void insertRecord( fstream &fRef )
{
Tool temp;
int part;
char name[ LENGTH ];

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

26
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295

Chapter 17 File Processing

int stock;
double price;
// ask user for part number
cout << "Enter the part number for insertion: ";
cin >> part;
// set file position pointer and read data from file
fRef.seekg( ( part ) * sizeof( Tool ) );
fRef.read( reinterpret_cast< char * > ( &temp ), sizeof( Tool ) );
// as long as record is empty get information from user
if ( temp.getPartNumber() == -1 )
{
temp.setPartNumber( part ); // set partNumber
cout << "Enter the tool name: "; // ask user for tool name
cin.ignore(); // ignore the newline on the input stream
cin.get( name, LENGTH );
temp.setToolName( name ); // set toolName
// ask user for new quantity and price
cout << "Enter quantity and price: ";
cin >> stock >> price;
temp.setInStock( stock ); // set quantity
temp.setUnitPrice( price ); // set price
// set file position pointer and write information to file
fRef.seekp( ( temp.getPartNumber() ) * sizeof( Tool ) );
fRef.write( reinterpret_cast< char * >( &temp ), sizeof( Tool ) );
} // end if
else
cerr << "Cannot insert. The record contains information.\n";
} // end function insertRecord
// function to delete a record
void deleteRecord( fstream &fRef )
{
Tool blankItem;
Tool temp;
int part;
// get tool user wants to delete
cout << "Enter the part number for deletion: ";
cin >> part;
// set file position pointer and read information from file
fRef.seekg( part * sizeof( Tool ) );
fRef.read( reinterpret_cast< char * >( &temp ), sizeof( Tool ) );
// if record contains data, set record to an empty Tool object
if ( temp.getPartNumber() != -1 )
{
fRef.seekp( part * sizeof( Tool ) );
fRef.write(

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Exercise Solutions
296
reinterpret_cast< char * >( &blankItem ), sizeof( Tool ) );
297
cout << "Record deleted.\n";
298
} // end if
299
else
300
cerr << "Cannot delete. The record is empty.\n";
301 } // end function deleteRecord

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

27

28

Chapter 17 File Processing

Should the file be initialized (Y or


Enter the part number (0 - 99, -1 to
Enter the tool name: Electric sander
Enter quantity and price: 7 57.98
Enter the part number (0 - 99, -1 to
Enter the tool name: Jig saw
Enter quantity and price: 21 11.00
Enter the part number (0 - 99, -1 to

N): y
end input): 3
end input): 24
end input): -1

Enter a choice:
1 List all tools.
2 Update record.
3 Insert record.
4 Delete record.
5 End program.
? 1
Record#
Tool name
3
Electric sander
24
Jig saw

Quantity
7
21

Cost
57.98
11.00

Quantity
7
70
21

Cost
57.98
11.99
11.00

Quantity
70

Cost
11.99

Enter a choice:
1 List all tools.
2 Update record.
3 Insert record.
4 Delete record.
5 End program.
? 3
Enter the part number for insertion: 17
Enter the tool name: Hammer
Enter quantity and price: 70 11.99
Enter a choice:
1 List all tools.
2 Update record.
3 Insert record.
4 Delete record.
5 End program.
? 1
Record#
Tool name
3
Electric sander
17
Hammer
24
Jig saw
Enter a choice:
1 List all tools.
2 Update record.
3 Insert record.
4 Delete record.
5 End program.
? 2
Enter the part number for update: 17
Record#
Tool name
17
Hammer
Enter the tool name: Hammer
Enter quantity and price: 76 11.99

continued at top of next page

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Exercise Solutions

Enter a choice:
1 List all tools.
2 Update record.
3 Insert record.
4 Delete record.
5 End program.
? 1
Record#
Tool name
3
Electric sander
17
Hammer
24
Jig saw

Quantity
7
76
21

Cost
57.98
11.99
11.00

Quantity
76
21

Cost
11.99
11.00

29

Enter a choice:
1 List all tools.
2 Update record.
3 Insert record.
4 Delete record.
5 End program.
? 4
Enter the part number for deletion: 3
Record deleted.
Enter a choice:
1 List all tools.
2 Update record.
3 Insert record.
4 Delete record.
5 End program.
? 1
Record#
Tool name
17
Hammer
24
Jig saw
Enter a choice:
1 List all tools.
2 Update record.
3 Insert record.
4 Delete record.
5 End program.
? 5

17.13 (Telephone Number Word Generator) Standard telephone keypads contain the digits 0
through 9. The numbers 2 through 9 each have three letters associated with them, as is indicated by
the following table:

Digit

Letter

ABC

DEF

GHI

JKL

MNO

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

30

Chapter 17 File Processing

Digit

Letter

PRS

TUV

WXY

Many people nd it difcult to memorize phone numbers, so they use the correspondence
between digits and letters to develop seven-letter words that correspond to their phone numbers.
For example, a person whose telephone number is 686-2377 might use the correspondence indicated in the above table to develop the seven-letter word NUMBERS.
Businesses frequently attempt to get telephone numbers that are easy for their clients to
remember. If a business can advertise a simple word for its customers to dial, then no doubt the
business will receive a few more calls.
Each seven-letter word corresponds to exactly one seven-digit telephone number. The restaurant wishing to increase its take-home business could surely do so with the number 825-3688 (i.e.,
TAKEOUT).
Each seven-digit phone number corresponds to many separate seven-letter words. Unfortunately, most of these represent unrecognizable juxtapositions of letters. It is possible, however, that
the owner of a barber shop would be pleased to know that the shops telephone number, 424-7288,
corresponds to HAIRCUT. The owner of a liquor store would, no doubt, be delighted to nd
that the stores telephone number, 233-7226, corresponds to BEERCAN. A veterinarian with the
phone number 738-2273 would be pleased to know that the number corresponds to the letters
PETCARE.
Write a C++ program that, given a seven-digit number, writes to a le every possible seven-letter word corresponding to that number. There are 2187 (3 to the seventh power) such words.
Avoid phone numbers with the digits 0 and 1.
ANS:

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

// Exercise 17.13 Solution: ex17_13.cpp


#include <iostream>
using std::cerr;
using std::cin;
using std::cout;
#include <fstream>
using std::ofstream;
#include <cstdlib>
using std::exit;
void wordGenerator( const int * const );
int main()
{
int phoneNumber[ 7 ] = { 0 }; // holds phone number
// prompt user to enter phone number
cout << "Enter a phone number (digits 2 through 9) "
<< "in the form: xxx-xxxx\n";

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Exercise Solutions
23
24
25
26
27
28
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76

31

// loop 8 times: 7 digits plus hyphen;


// hyphen is not placed in phoneNumber
for ( int u = 0, v = 0; u < 8; u++ )
{
int i = cin.get();
// test if i is between 0 and 9
if ( i >= '0' && i <= '9' )
phoneNumber[ v++ ] = i - '0';
} // end for
wordGenerator( phoneNumber ); // form words from phone number
return 0;
} // end main
// function to form words based on phone number
void wordGenerator( const int * const n )
{
// set output stream and open output file
ofstream outFile( "phone.dat" );
// letters corresponding to each number
const char *phoneLetters[ 10 ] = { "", "", "ABC", "DEF", "GHI", "JKL",
"MNO", "PRS", "TUV", "WXY" };
// terminate if file could not be opened
if ( !outFile )
{
cerr << "\"phone.dat\" could not be opened.\n";
exit( 1 );
} // end if
int count = 0; // number of words found
// output all possible combinations
for ( int i1 = 0; i1 <= 2; i1++ )
{
for ( int i2 = 0; i2 <= 2; i2++ )
{
for ( int i3 = 0; i3 <= 2; i3++ )
{
for ( int i4 = 0; i4 <= 2; i4++ )
{
for ( int i5 = 0; i5 <= 2; i5++ )
{
for ( int i6 = 0; i6 <= 2; i6++ )
{
for ( int i7 = 0; i7 <= 2; i7++ )
{
outFile << phoneLetters[ n[ 0 ] ][ i1 ]
<< phoneLetters[ n[ 1 ] ][ i2 ]
<< phoneLetters[ n[ 2 ] ][ i3 ]
<< phoneLetters[ n[ 3 ] ][ i4 ]
<< phoneLetters[ n[ 4 ] ][ i5 ]

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

32

Chapter 17 File Processing

77
<< phoneLetters[ n[ 5 ] ][ i6 ]
78
<< phoneLetters[ n[ 6 ] ][ i7 ] << ' ';
79
80
if ( ++count % 9 == 0 ) // form rows
81
outFile << '\n';
82
} // end for
83
} // end for
84
} // end for
85
} // end for
86
} // end for
87
} // end for
88
} // end for
89
90
// output phone number
91
outFile << "\nPhone number is ";
92
93
for ( int i = 0; i < 7; i++ )
94
{
95
if ( i == 3 )
96
outFile << '-';
97
98
outFile << n[ i ];
99
} // end for
100
101
outFile.close(); // close output file
102 } // end function wordGenerator
Enter a phone number (digits 2 through 9) in the form: xxx-xxxx
568-9876

Contents of phone.dat
JMTWTPM
JMTWUPM
JMTWVPM
JMTXTPM
JMTXUPM
JMTXVPM
...

JMTWTPN
JMTWUPN
JMTWVPN
JMTXTPN
JMTXUPN
JMTXVPN

JMTWTPO
JMTWUPO
JMTWVPO
JMTXTPO
JMTXUPO
JMTXVPO

JMTWTRM
JMTWURM
JMTWVRM
JMTXTRM
JMTXURM
JMTXVRM

JMTWTRN
JMTWURN
JMTWVRN
JMTXTRN
JMTXURN
JMTXVRN

JMTWTRO
JMTWURO
JMTWVRO
JMTXTRO
JMTXURO
JMTXVRO

JMTWTSM
JMTWUSM
JMTWVSM
JMTXTSM
JMTXUSM
JMTXVSM

JMTWTSN
JMTWUSN
JMTWVSN
JMTXTSN
JMTXUSN
JMTXVSN

JMTWTSO
JMTWUSO
JMTWVSO
JMTXTSO
JMTXUSO
JMTXVSO

LOVXVPM
LOVYTPM
LOVYUPM
LOVYVPM

LOVXVPN
LOVYTPN
LOVYUPN
LOVYVPN

LOVXVPO
LOVYTPO
LOVYUPO
LOVYVPO

LOVXVRM
LOVYTRM
LOVYURM
LOVYVRM

LOVXVRN
LOVYTRN
LOVYURN
LOVYVRN

LOVXVRO
LOVYTRO
LOVYURO
LOVYVRO

LOVXVSM
LOVYTSM
LOVYUSM
LOVYVSM

LOVXVSN
LOVYTSN
LOVYUSN
LOVYVSN

LOVXVSO
LOVYTSO
LOVYUSO
LOVYVSO

Phone number is 568-9876

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Exercise Solutions

33

17.14 Write a program that uses the sizeof operator to determine the sizes in bytes of the various
data types on your computer system. Write the results to the file datasize.dat, so that you may
print the results later. The results should be displayed in two-column format with the type name in
the left column and the size of the type in right column, as in:
char
unsigned char
short int
unsigned short int
int
unsigned int
long int
unsigned long int
float
double
long double

1
1
2
2
4
4
4
4
4
8
10

[Note: The sizes of the built-in data types on your computer might differ from those listed above.]
ANS:

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
30
31
32
33

// Exercise 17.14 Solution: ex17_14.cpp


#include <iostream>
using std::cerr;
using std::endl;
#include <iomanip>
using std::setw;
#include <fstream>
using std::ofstream;
#include <cstdlib>
using std::exit;
int main()
{
// assign stream to file and open file
ofstream outFile( "datasize.dat" );
// terminate program if output file cannot be opened
if ( !outFile )
{
cerr << "Unable to open \"datasize.dat\".\n";
exit( 1 );
} // end if
// write size of char, unsigned char,
// short int, unsigned short int and int to file
outFile << "Data type" << setw( 24 ) << "Size\nchar" << setw( 21 )
<< sizeof( char ) << "\nunsigned char" << setw( 12 )
<< sizeof( unsigned char ) << "\nshort int" << setw( 16 )
<< sizeof( short int ) << "\nunsigned short int" << setw( 7 )
<< sizeof( unsigned short ) << "\nint" << setw( 22 )

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

34
34
35
36
37
38
39
40
41
42
43
44
45
46
47

Chapter 17 File Processing

<< sizeof( int ) << '\n';


// write size of unsigned int, long int, unsigned long int
// float, double and long double to file
outFile << "unsigned int" << setw( 13 ) << sizeof( unsigned )
<< "\nlong int" << setw( 17 ) << sizeof( long )
<< "\nunsigned long int" << setw( 8 ) << sizeof( unsigned long )
<< "\nfloat" << setw( 20 ) << sizeof( float )
<< "\ndouble" << setw( 19 ) << sizeof( double )
<< "\nlong double" << setw( 14 ) << sizeof( long double ) << endl;
outFile.close(); // close output file
return 0;
} // end main

Contents of datasize.dat
Data type
char
unsigned char
short int
unsigned short int
int
unsigned int
long int
unsigned long int
float
double
long double

Size
1
1
2
2
4
4
4
4
4
8
8

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Potrebbero piacerti anche