Professional Documents
Culture Documents
Chapter 8
I/O streams and data files
11:05:19
8.1 I/O file stream objects and methods
Files
The following statement connects the external file named prices.dat to the
internal file stream object named inFile:
i n F i l e . open ( ” p r i c e s . d a t ” ) ;
The following statement connects the external file named prices.dat to the
internal file stream object named outFile:
o u t F i l e . open ( ” p r i c e s . d a t ” ) ;
Prototype Description
fail() Returns a Boolean true if the file hasnt been opened suc-
cessfully; otherwise, returns a Boolean false value.
eof() Returns a Boolean true if a read has been attempted past
the end-of-file; otherwise, returns a Boolean false value.
The value becomes true only when the first character af-
ter the last valid file character is read.
good() Returns a Boolean true value while the file is available for
program use. Returns a Boolean false value if a read has
been attempted past the end-of-file. The value becomes
false only when the first character after the last valid file
character is read.
bad() Returns a Boolean true value if a read has been attempted
past the end-of-file; otherwise, returns a false. The value
becomes true only when the first character after the last
valid file character is read.
Example 8.1:
using namespace s t d ;
i n t main ( ) {
ifstream inFile ;
i n F i l e . open ( ” p r i c e s . d a t ” ) ; / / open t h e f i l e w i t h t h e
/ / e x t e r n a l name p r i c e s . d a t
i f ( i n F i l e . f a i l ( ) ) / / check f o r a s u c c e s s f u l open
{
c o u t << ” \nThe f i l e was n o t s u c c e s s f u l l y opened ”
<< ” \n Please check t h a t t h e f i l e c u r r e n t l y e x i s t s . ”
<< e n d l ;
exit (1);
}
c o u t << ” \nThe f i l e has been s u c c e s s f u l l y opened f o r
r e a d i n g . ” << e n d l ;
/ / st at ement s t o read data from t h e f i l e would be
/ / placed here
r et ur n 0 ;
}
Output mode:
A different check is required for output files (files that are written to)
because if a file exists with the same name as the file to be opened in
output mode, the existing file is erased and all its data is lost.
To avoid this situation, the file is first opened in input mode to see whether
it exists. If it does, the user is given the choice of permitting it to be
overwritten when its opened later in output mode.
Example 8.2:
using namespace s t d ;
i n t main ( ) {
ifstream inFile ;
of st r eam o u t F i l e ;
/ / a t t e m p t t o open t h e f i l e f o r i n p u t
i n F i l e . open ( ” p r i c e s . d a t ” ) ;
char response ;
/ / i f i t doesn ’ t f a i l , t h e f i l e e x i s t s
if (! inFile . f a i l ())
{
c o u t << ” A f i l e by t h e name p r i c e s . d a t e x i s t s . \ n ”
<< ” Do you want t o c o n t i n u e and o v e r w r i t e i t \n ”
<< ” w i t h t h e new data ( y o r n ) : ” ;
c i n >> response ;
i f ( t o l o w e r ( response ) == ’ n ’ ) {
c o u t << ” The e x i s t i n g f i l e w i l l n o t be o v e r w r i t t e n . ”
<< e n d l ;
e x i t ( 1 ) ; / / t e r m i n a t e program e x e c u t i o n
}
}
/ / now open t h e f i l e f o r w r i t i n g
o u t F i l e . open ( ” p r i c e s . d a t ” ) ;
i f ( i n F i l e . f a i l ( ) ) / / check f o r a s u c c e s s f u l open
{
c o u t << ” \nThe f i l e was n o t s u c c e s s f u l l y opened ”
<< e n d l ;
exit (1);
}
c o u t << ” The f i l e has been s u c c e s s f u l l y opened f o r
output . ”
<< e n d l ;
/ / st at ement s t o w r i t e t o t h e f i l e would be placed here
r et ur n 0 ;
}
Example 8.3:
using namespace s t d ;
i n t main ( ) {
s t r i n g f i l e n a m e = ” p r i c e s . d a t ” ; / / place t h e f i l e n a m e
ifstream inFile ;
i n F i l e . open ( f i l e n a m e . c s t r ( ) ) ; / / open t h e f i l e
i f ( i n F i l e . f a i l ( ) ) / / check f o r s u c c e s s f u l open
{
c o u t << ” \nThe f i l e named ” << f i l e n a m e
<< ” was n o t s u c c e s s f u l l y opened ”
String objects can be used to permit users to enter the filename as the
program is executing. For example
c o u t << ” Ent er t h e name o f t h e f i l e t o be opened : ” ;
c i n >> f i l e n a m e ;
Example 8.4:
using namespace s t d ;
i n t main ( ) {
s t r i n g filename ;
ifstream inFile ;
c o u t << ” Ent er t h e name o f t h e f i l e t o be opened : ” ;
c i n >> f i l e n a m e ;
i n F i l e . open ( f i l e n a m e . c s t r ( ) ) ; / / open t h e f i l e
i f ( i n F i l e . f a i l ( ) ) / / check f o r s u c c e s s f u l open
{
c o u t << ” \nThe f i l e named ” << f i l e n a m e
Higher level programming language
11:05:21
8.1 I/O file stream objects and methods
Indicator Description
ios::in Open a text file in input mode
ios::out Open a text file in output mode
ios::app Open a text file in append mode
ios::ate Go to the end of the opened file
ios::binary Open a binary file in input mode (default is text file)
ios::trunc Delete file contents if it exists
ios::nocreate If file doesnt exist, open fails
ios::noreplace If file exists, open for output fails
An fstream file object opened in append mode means an existing file is
available for data to be added to the end of the file. If the file opened for
appending doesnt exist, a new file with the designated name is created
and made available to receive output from the program.
Notes:
If the mode indicator is omitted as the second argument for an ifstream
object, the stream is opened as a text input file by default; if the mode
indicator is omitted for an ofstream object, the stream is opened as a text
output file by default.
Closing a file:
A file is closed by using the close() method. This method breaks the
connection between the files external name and the file stream object,
which can be used for another file. The following statement closes the
inFile streams connection to its current file:
i n F i l e . close ( ) ;
The close() method takes no argument.
Because all computers have a limit on the maximum number of files that
can be open at one time, closing files that are no longer needed makes
good sense.
Solution:
Solution:
Example 8.7:
using namespace s t d ;
i n t main ( ) {
exit (1);
}
/ / s e t t h e o u t p u t f i l e stream f o r m a t s
o u t F i l e << s e t i o s f l a g s ( i o s : : f i x e d )
<< s e t i o s f l a g s ( i o s : : showpoint )
<< s e t p r e c i s i o n ( 2 ) ;
/ / send data t o t h e f i l e
o u t F i l e << ” Mats ” << 39.95 << e n d l
<< ” Bulbs ” << 3.22 << e n d l
<< ” Fuses ” << 1.08 << e n d l ;
o u t F i l e . close ( ) ;
c o u t << ” The f i l e ” << f i l e n a m e
<< ” has been s u c c e s s f u l l y w r i t t e n . ” << e n d l ;
r et ur n 0 ;
}
Notes:
When the above program runs, the prices.dat file is created and saved by
the computer as a text file. Its a sequential file consisting of the following
data:
Mats 39.95
Bulbs 3.22
Fuses 1.08
The actual storage of characters in the file depends on the character
codes the computer uses. Although only 30 characters appear to be
stored in the file, corresponding to the descriptions, blanks, and prices
written to the file, the file contains 36 characters.
The extra characters consist of the newline escape sequence at the end
of each line created by the endl manipulator, which is created as a
carriage return character (cr) and linefeed (lf).
Example 8.8:
using namespace s t d ;
i n t main ( ) {
s t r i n g filename = ” prices . dat ” ; / / put the filename
s t r i n g descrip ;
double p r i c e ;
ifstream inFile ;
i n F i l e . open ( f i l e n a m e . c s t r ( ) ) ;
i f ( i n F i l e . f a i l ( ) ) / / check f o r s u c c e s s f u l open
{
c o u t << ” \nThe f i l e was n o t s u c c e s s f u l l y opened ”
Higher level programming language
11:05:29
8.2 Reading and writing character-based files
a. Create a text file containing the following data (without the headings):
Car Number Miles Driven Gallons of Gas Used
54 250 19
62 525 38
71 123 6
85 1322 86
97 235 14
b. Write a C++ program that reads the data in the file created in (a) and
displays the car number, miles driven, gallons of gas used, and miles
per gallon (mpg) for each car. The output should contain the total miles
driven, total gallons of gas used, and average mpg for all cars. These
totals should be displayed at the end of the output report.
Notes:
The expression
i n F i l e >> d e s c r i p >> p r i c e
can be replaced by a getline() method (see Table 8.3). For file input, this
method has the following syntax:
g e t l i n e ( f i l e O b j e c t , strObj , terminatingChar )
where fileObject is the name of the ifstream file, strObj is a string class
object, and terminatingChar is an optional character constant or variable
specifying the terminating character. If this optional third argument is
omitted, the default terminating character is the newline (’\n’) character.
Example 8.10:
using namespace s t d ;
i n t main ( ) {
s t r i n g filename = ” prices . dat ” ; / / put the filename
string line ;
ifstream inFile ;
i n F i l e . open ( f i l e n a m e . c s t r ( ) ) ;
i f ( i n F i l e . f a i l ( ) ) { / / check f o r s u c c e s s f u l open
c o u t << ” \nThe f i l e was n o t s u c c e s s f u l l y opened ”
<< ” \n Please check t h a t t h e f i l e c u r r e n t l y e x i s t s . ”
<< e n d l ;
Higher level programming language
11:05:30
8.2 Reading and writing character-based files
exit (1);
}
/ / read and d i s p l a y t h e f i l e ’ s c o n t e n t s
while ( g e t l i n e ( i n F i l e , l i n e ) )
c o u t << l i n e << e n d l ;
i n F i l e . close ( ) ;
r et ur n 0 ;
}
a. Write a C++ program that accepts lines of text from the keyboard and
writes each line to a file named text.dat until an empty line is entered.
An empty line is a line with no text thats created by pressing the Enter
(or Return) key.
b. Modify a to read and display the data stored in the text.dat file
created in a.
There are two types of file access: sequential access and random
access.
• Characters in the file are stored in a sequential manner.
• Characters are accessed one after another, which is called sequential
access.
• Although characters are stored sequentially, they do not have to be
accessed the same way. In fact, we can skip over characters and read
a sequentially organized file in a nonsequential manner.
• In random access, any character in the opened file can be read without
having to sequentially read all characters stored ahead of it first.
• To provide random access to files, each ifstream object creates a file
position marker automatically. This marker is a long integer
representing an offset from the beginning of the file and keeps track of
where the next character is to be read from or written to.
The offset passed to seekg() and seekp() must be a long integer, hence
the uppercase L appended to each number in the method calls.
Mode:
Name Description
ios::beg The beginning of the file.
ios::cur) Current position.
ios::end The end of the file.
The tell() methods return the file position markers offset value. For
example, if 10 characters have been read from an input file named inFile,
the method call
inFile . tellg ();
returns the long integer 10. This means the next character to be read is
offset 10 byte positions from the start of the file and is the 11th character
in the file.
Example 8.12: Assume the test.dat file contains the following characters:
The grade was 92.5
The following program shows using seekg() and tellg() to read a file in
reverse order.
# include <iost r eam>
# include <fstream >
# include <s t r i n g >
# include <c s t d l i b >
using namespace s t d ;
i n t main ( ) {
s t r i n g filename = ” t e s t . dat ” ;
char ch ;
long o f f s e t , l a s t ;
ifstream i n F i l e ( filename . c s t r ( ) ) ;
Higher level programming language
11:05:32
8.3 Random file access
i f ( i n F i l e . f a i l ( ) ) { / / check f o r s u c c e s s f u l open
c o u t << ” \nThe f i l e was n o t s u c c e s s f u l l y opened ”
<< ” \n Please check t h a t t h e f i l e c u r r e n t l y e x i s t s ”
<< e n d l ;
exit (1);
}
i n F i l e . seekg ( 0 L , i o s : : end ) ; / / move t o t h e end o f t h e f i l e
/ / save t h e o f f s e t o f t h e l a s t c h a r a c t e r
last = inFile . tellg () ;
f o r ( o f f s e t = 1L ; o f f s e t <= l a s t ; o f f s e t ++){
i n F i l e . seekg(− o f f s e t , i o s : : end ) ;
ch = i n F i l e . g e t ( ) ;
c o u t << ch << ” : ” ;
}
i n F i l e . close ( ) ;
c o u t << e n d l ;
r et ur n 0 ;
} Higher level programming language
11:05:33
8.3 Random file access
Example 8.13 (Practice): Rewrite the above program so that the origin
for the seekg() method used in the for loop is the start of the file rather
than the end.
Example 8.14 (Practice): Using the seek() and tell() methods, write a
function named fileChars() that returns the total number of characters in a
file.