Reading Data from a Sequential File

Files store data so it may be retrieved for processing when needed. The previous section demonstrated how to create a file for sequential access. In this section, we discuss how to read data sequentially from a file.

Figure 17.7 reads records from the clients.dat file that we created using the program of Fig. 17.4 and displays the contents of these records. Creating an ifstream object opens a file for input. The ifstream constructor can receive the filename and the file open mode as arguments. Line 31 creates an ifstream object called inClientFile and associates it with the clients.dat file. The arguments in parentheses are passed to the ifstream constructor function, which opens the file and establishes a "line of communication" with the file.

Figure 17.7. Reading and printing a sequential file.

(This item is displayed on pages 850 - 851 in the print version)

 1 // Fig. 17.7: Fig17_07.cpp
 2 // Reading and printing a sequential file.
 3 #include 
 4 using std::cerr;
 5 using std::cout;
 6 using std::endl;
 7 using std::fixed;
 8 using std::ios;
 9 using std::left;
10 using std::right;
11 using std::showpoint;
12
13 #include  // file stream 
14 using std::ifstream; // input file stream
15
16 #include 
17 using std::setw;
18 using std::setprecision;
19
20 #include 
21 using std::string;
22
23 #include 
24 using std::exit; // exit function prototype
25
26 void outputLine( int, const string, double ); // prototype
27
28 int main()
29 {
30 // ifstream constructor opens the file 
31 ifstream inClientFile( "clients.dat", ios::in );
32
33 // exit program if ifstream could not open file
34 if ( !inClientFile )
35 {
36 cerr << "File could not be opened" << endl;
37 exit( 1 );
38 } // end if
39
40 int account;
41 char name[ 30 ];
42 double balance;
43
44 cout << left << setw( 10 ) << "Account" << setw( 13 )
45 << "Name" << "Balance" << endl << fixed << showpoint;
46
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 } // end main
53
54 // display single record from file
55 void outputLine( int account, const string name, double balance )
56 {
57 cout << left << setw( 10 ) << account << setw( 13 ) << name
58 << setw( 7 ) << setprecision( 2 ) << right << balance << endl;
59 } // 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
 

Good Programming Practice 17.1

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


Objects of class ifstream are opened for input by default. We could have used the statement

ifstream inClientFile( "clients.dat" );

to open clients.dat for input. Just as with an ofstream object, an ifstream object can be created without opening a specific file, because a file can be attached to it later.

The program uses the condition !inClientFile to determine whether the file was opened successfully before attempting to retrieve data from the file. Line 48 reads a set of data (i.e., a record) from the file. After the preceding line is executed the first time, account has the value 100, name has the value "Jones" and balance has the value 24.98. Each time line 48 executes, it reads another record from the file into the variables account, name and balance. Line 49 displays the records, using function outputLine (lines 5559), which uses parameterized stream manipulators to format the data for display. When the end of file has been reached, the implicit call to operator void * in the while condition returns the null pointer (which converts to the bool value false), the ifstream destructor function closes the file and the program terminates.

To retrieve data sequentially from a file, programs normally start reading from the beginning of the file and read all the data consecutively until the desired data is found. It might be necessary to process the file sequentially several times (from the beginning of the file) during the execution of a program. Both istream and ostream provide member functions for repositioning the file-position pointer (the byte number of the next byte in the file to be read or written). These member functions are seekg ("seek get") for istream and seekp ("seek put") for ostream. Each istream object has a "get pointer," which indicates the byte number in the file from which the next input is to occur, and each ostream object has a "put pointer," which indicates the byte number in the file at which the next output should be placed. The statement

inClientFile.seekg( 0 );

repositions the file-position pointer to the beginning of the file (location 0) attached to inClientFile. The argument to seekg normally is a long integer. A second argument can be specified to indicate the seek direction. The seek direction can be ios::beg (the default) for positioning relative to the beginning of a stream, ios::cur for positioning relative to the current position in a stream or ios::end for positioning relative to the end of a stream. The file-position pointer is an integer value that specifies the location in the file as a number of bytes from the file's starting location (this is also referred to as the offset from the beginning of the file). Some examples of positioning the "get" file-position pointer are


// position to the nth byte of fileObject (assumes ios::beg)
fileObject.seekg( n );

// position n bytes forward in fileObject
fileObject.seekg( n, ios::cur );

// position n bytes back from end of fileObject
fileObject.seekg( n, ios::end );

// position at end of fileObject
fileObject.seekg( 0, ios::end );

The same operations can be performed using ostream member function seekp. Member functions tellg and tellp are provided to return the current locations of the "get" and "put" pointers, respectively. The following statement assigns the "get" file-position pointer value to variable location of type long:

location = fileObject.tellg();

Figure 17.8 enables a credit manager to display the account information for those customers with zero balances (i.e., customers who do not owe the company any money), credit (negative) balances (i.e., customers to whom the company owes money), and debit (positive) balances (i.e., customers who owe the company money for goods and services received in the past). The program displays a menu and allows the credit manager to enter one of three options to obtain credit information. Option 1 produces a list of accounts with zero balances. Option 2 produces a list of accounts with credit balances. Option 3 produces a list of accounts with debit balances. Option 4 terminates program execution. Entering an invalid option displays the prompt to enter another choice.

Figure 17.8. Credit inquiry program.

(This item is displayed on pages 852 - 855 in the print version)

 1 // Fig. 17.8: Fig17_08.cpp
 2 // Credit inquiry program.
 3 #include 
 4 using std::cerr;
 5 using std::cin;
 6 using std::cout;
 7 using std::endl;
 8 using std::fixed;
 9 using std::ios;
10 using std::left;
11 using std::right;
12 using std::showpoint;
13
14 #include  
15 using std::ifstream;
16
17 #include 
18 using std::setw;
19 using std::setprecision;
20
21 #include 
22 using std::string;
23
24 #include 
25 using std::exit; // exit function prototype
26
27 enum RequestType { ZERO_BALANCE = 1, CREDIT_BALANCE, DEBIT_BALANCE, END };
28 int getRequest();
29 bool shouldDisplay( int, double );
30 void outputLine( int, const string, double );
31
32 int main()
33 {
34 // ifstream constructor opens the file 
35 ifstream inClientFile( "clients.dat", ios::in );
36
37 // exit program if ifstream could not open file
38 if ( !inClientFile )
39 {
40 cerr << "File could not be opened" << endl;
41 exit( 1 );
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
52 // process user's request
53 while ( request != END )
54 {
55 switch ( request )
56 {
57 case ZERO_BALANCE:
58 cout << "
Accounts with zero balances:
";
59 break;
60 case CREDIT_BALANCE:
61 cout << "
Accounts with credit balances:
";
62 break;
63 case DEBIT_BALANCE:
64 cout << "
Accounts with debit balances:
";
65 break;
66 } // end switch
67
68 // read account, name and balance from file
69 inClientFile >> account >> name >> balance;
70
71 // display file contents (until eof)
72 while ( !inClientFile.eof() )
73 {
74 // display record
75 if ( shouldDisplay( request, balance ) )
76 outputLine( account, name, balance );
77
78 // read account, name and balance from file
79 inClientFile >> account >> name >> balance;
80 } // end inner while
81
82 inClientFile.clear(); // reset eof for next input 
83 inClientFile.seekg( 0 ); // reposition to beginning of file
84 request = getRequest(); // get additional request from user
85 } // end outer while
86
87 cout << "End of run." << endl;
88 return 0; // ifstream destructor closes the file
89 } // end main
90
91 // obtain request from user
92 int getRequest()
93 {
94 int request; // request from user
95
96 // display request options
97 cout << "
Enter request" << endl
98 << " 1 - List accounts with zero balances" << endl
99 << " 2 - List accounts with credit balances" << endl
100 << " 3 - List accounts with debit balances" << endl
101 << " 4 - End of run" << fixed << showpoint;
102
103 do // input user request
104 {
105 cout << "
? ";
106 cin >> request;
107 } while ( request < ZERO_BALANCE && request > END );
108
109 return request;
110 } // end function getRequest
111
112 // determine whether to display given record
113 bool shouldDisplay( int type, double balance )
114 {
115 // determine whether to display zero balances
116 if ( type == ZERO_BALANCE && balance == 0 )
117 return true;
118
119 // determine whether to display credit balances
120 if ( type == CREDIT_BALANCE && balance < 0 )
121 return true;
122
123 // determine whether to display debit balances
124 if ( type == DEBIT_BALANCE && balance > 0 )
125 return true;
126
127 return false;
128 } // end function shouldDisplay
129
130 // display single record from file
131 void outputLine( int account, const string name, double balance )
132 {
133 cout << left << setw( 10 ) << account << setw( 13 ) << name
134 << setw( 7 ) << setprecision( 2 ) << right << balance << endl;
135 } // end function outputLine
 
 Enter request
 1 - List accounts with zero balances
 2 - List accounts with credit balances
 3 - List accounts with debit balances
 4 - End of run
 ? 1

 Accounts with zero balances:
 300 White 0.00

 Enter request
 1 - List accounts with zero balances
 2 - List accounts with credit balances
 3 - List accounts with debit balances
 4 - End of run
 ? 2

 Accounts with credit balances:
 400 Stone -42.16

 Enter request
 1 - List accounts with zero balances
 2 - List accounts with credit balances
 3 - List accounts with debit balances
 4 - End of run
 ? 3

 Accounts with debit balances:
 100 Jones 24.98
 200 Doe 345.67
 500 Rich 224.62

 Enter request
 1 - List accounts with zero balances
 2 - List accounts with credit balances
 3 - List accounts with debit balances
 4 - End of run
 ? 4
 End of run.
 

Introduction to Computers, the Internet and World Wide Web

Introduction to C++ Programming

Introduction to Classes and Objects

Control Statements: Part 1

Control Statements: Part 2

Functions and an Introduction to Recursion

Arrays and Vectors

Pointers and Pointer-Based Strings

Classes: A Deeper Look, Part 1

Classes: A Deeper Look, Part 2

Operator Overloading; String and Array Objects

Object-Oriented Programming: Inheritance

Object-Oriented Programming: Polymorphism

Templates

Stream Input/Output

Exception Handling

File Processing

Class string and String Stream Processing

Web Programming

Searching and Sorting

Data Structures

Bits, Characters, C-Strings and structs

Standard Template Library (STL)

Other Topics

Appendix A. Operator Precedence and Associativity Chart

Appendix B. ASCII Character Set

Appendix C. Fundamental Types

Appendix D. Number Systems

Appendix E. C Legacy Code Topics

Appendix F. Preprocessor

Appendix G. ATM Case Study Code

Appendix H. UML 2: Additional Diagram Types

Appendix I. C++ Internet and Web Resources

Appendix J. Introduction to XHTML

Appendix K. XHTML Special Characters

Appendix L. Using the Visual Studio .NET Debugger

Appendix M. Using the GNU C++ Debugger

Bibliography



C++ How to Program
C++ How to Program (5th Edition)
ISBN: 0131857576
EAN: 2147483647
Year: 2004
Pages: 627

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net