Streams and Files
Chapter
12 in Lafore
Chapter
9 in Weiss
What are streams
A stream is a general name given to a flow of data
In C++ a stream is represented by an object of
a stream class
We have been using cin and cout as stream objects
They are
predefined objects of classes derived from the istream
and ostream classes for standard I/O
If you want to do file I/O, you define different
objects to go with the insertion (<<) and extraction operators (>>)
Use cin and cout for standard I/O,
define other objects for file I/O
Stream basics
A stream is a logical device that either produces
or consumes information
A stream is linked to a physical device by the
I/O system.
This physical
device can be the monitor, keyboard, disk drive, or others
All streams behave in the same way even though they
may be connected to different physical devices
Because all streams behave the same way, the same I/O
functions can operate on virtually any type of physical device
The advantage is that you need to learn only one I/O
system.
Stream class hierarchy
The ios class is the super class of most stream classes
It has many
member functions which are then inherited by its derived classes
Formatting flags
and manipulators are members of the ios class
The istream and ostream classes are derived from the ios class
The ifstream class is derived from the istream class
The ofstream class is derived from the ostream class
The reason it is
important to know about the hierarchy is so you understand that they have the
same member functions that can be used.
Formatted I/O
The C++ I/O system allows you to format I/O operations
For example, you can set field widths, left or right
justify, or say how many digits after the decimal.
There are two conceptually different ways to format
data
You can set
various format status flags defined inside the ios class
You can use special functions called manipulators
Often there is more than one way to do something
Formatting flags of the ios
class
Formatting flags are a set of enumeration definitions
in the ios class
They act as on/off switches to format output
There are different ways the flags can be set, but all
can be set using the setf( ) and unsetf( ) iso member functions
Example: note
that you must use the scope resolution operator
cout.setf(iso::left); // left justifies the output
cout >> whatever ;
cout.unsetf(ios::left);
Other formatting flags
Manipulators
Manipulators are formatting instructions inserted
directly into a stream
endl is an often used manipulator
Some manipulators have arguments, others do not.
Except for the flags and manipulators you use
regularly, you will
want to
have a reference nearby.
Examples using manipulators
cout << setw(15) //
set next filed width to 15
cout
<< left; //field on left, padding on right
cout
<< right; // field on right, padding on left;
cout<<
setprecision(2);
// two decimal places
cout
<< scientific; // out double w/ scientific notation
ostream&
operator << (ostream& s, Person& p)
{
s << setw(20) << left << p.name
<< setw(30)
<< p.address
<< p.phone
<< endl;
}
Disk file I/O with streams
Working with disk files requires the classes ifstream and ofstream
You must #include
<fstream> to use these classes
These two classes are derived from istram
and ostream, so they inherit all their member
functions
Formatted file I/O
Numbers are
stored on disk as a series of characters
5.23 is stored as
ASCII 5, ASCII ., ASCII 2, and ASCII 3, not at a float
or double
Next slide is an example writing data to a file
#include <fstream> #include <iostream>
#include <string>
using namespace std;
int main( )
{
char ch =
'x';
int num=
77;
double dou
= 6.02;
string str1 = John Doe";
string str2 = Bozeman, MT 59715";
ofstream ofile("fdata.txt"); //create ofstream
object
ofile << ch //insert (write) data
<< num
<< ' ' //needs
space between numbers
<< dou
<< str1
<< \n ' //need newline
between strings
<< str2;
return 0;
}
Detecting end-of-file
The EOF is a signal sent to the program from the
operating system when there is no more data to read
One way to check
for this is:
while (!infile.eof(
))
Another way is:
while (infile.good( ) )
This will check
for any error conditions
Another way is:
while (infile)
This tests the
stream directly. As long as everything isgoing well, this will return a nonzero value.
At eof or any error condition it will return a zero
Opening files
When you declare an object of type ofstream or ifstream along with the file name, the file is opened
automatically
If you open a file this way, you accept some defaults
The default for
an ifstream object is to open the file to begin reading at the
beginning of the file
The default for an ofstream object is to overwrite the file
You can change
these defaults using mode bits, used this way
ofstream ofile;
ofile.open(myFile, ios::app);
Mode bits
Closing files
It is not usually necessary to close files explicitly
because they are closed automatically
when the
stream goes out of scope
Their destructors are called and close the file
You may want to use an explicit close( ) every time you close a file, without
relying
on the streams destructor.
If you open a file for reading, then want to write to
it, you must close it for reading
before
opening it for writing.
The getline( ) function
There are two versions of the getline( ) function
One is a global function that is used with
string data, used this way
getline(infile, name); or
getline(cin,
name);
The other is a member function of the ios class which has to be called with an object derived
from the ios class
infile.getline(str, 255); or
cin.getline(str,
100);
The second
argument is the number of characters in the char array.
Both versions
have a third argument which is the delimiter; it defaults to \n
Writing Objects to files
Lafore does this using the reinterpret_cast operator
The reinterpret_cast tells the compiler I know you wont
like this, but I want to do it anyway
It changes the type of a section of memory without
caring whether it makes sense.
This is an unsafe programming practice, but you can
read about it and use it if you want.
Page 591