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 stream’s 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 won’t 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