Basic File I/O
 

Input/Ouput to and from files:

File input and file output is an essential in programming.  Most software involves more than keyboard input and screen user interfaces.  Data needs to be stored somewhere when a program is not running, and that means writing data to disk.  For this, we need file input and file output techniques.

Fortunately, this is EASY in C++!  If you know how to do screen output with cout, and keyboard input with cin, then you already know most of it!  File I/O works the same way.  The primary difference is that you use objects other than cout and cin.

First, we'll need to create new stream objects.  cout and cin are of types ostream and istream:

  ostream cout;
  istream cin; 

For input and output with files, you need to use types called ofstream (for "output file stream") and ifstream (for "input file stream").  You can declare your own objects with these types, but first you need to include the <fstream> library file:

  #include <fstream> 

  ofstream out1, bob;    // create file output streams, called out1 and bob
  ifstream in1, joe;     // create file input streams, called in1 and joe 

Once you create stream objects, you'll need to attach them to actual files.  The filename is a c-style string (i.e. string literal or character array).  You can do this with a function called "open", which is a member function of the stream classes:

  out1.open("outfile1.txt");

  char filename[20] = "bobfile";
  bob.open(filename);

  in1.open("infile1.txt");

  char joefile[15] = "joedude";
  joe.open(joefile); 
Files can also be attached to ifstream and ofstream objects by passing the filename as a parameter to the constructor (an alternate method to using open), as the stream objects are created. Examples:
  ofstream out1("outfile1.txt");
  ifstream in1("infile1.txt");

After attaching the stream to a file, it is always a good idea to make sure there is actually a valid file attached. (For instance, an attempt to open an input file might have used an invalid filename). One easy way is to test the true/false value of the stream object itself. A stream that is not attached to a valid source of input (or output destination) will evaluate as a 0 (like a null pointer) -- i.e. false.

   if (!in1)	// if in1 not attached to a valid input source, abort
   {
	cout << "Sorry, bad file.";
	exit(0);
   }
If we're doing error checking, where the filename is coming from user input, for example, then an attempt to open a bad file will set a fail flag in the stream. This needs to be cleared before another attempt to open a file. Do this with member function clear().
  char filename[30];
  ifstream fin;
  cin >> filename;
  fin.open(filename);
  if (!fin)
  {
     cout << "Bad file...";
     fin.clear();			// resets stream to "good" status
  }
  // now we can try another fin.open() operation
When finished with a file, it can be detached from the stream object with the member function close. Examples:
  in1.close();
  out1.close();
  bob.close(); 
Note that the close function simply closes the file. It does not get rid of the stream object. The stream object can now be used to attach to another file, if desired:
  in1.open("infile2.txt");
Another useful member function of the stream classes is eof(), which stands for end of file. This returns a bool value, indicating whether the next character on the stream is the "end of file" character or not. It is useful in file operations, as it can indicate whether the end of an input file has been reached, when reading sequentially.
  char ch;
  while (!in1.eof())	// while not at the end of the file
  {
     in1.get(ch);	// read a character
     cout << ch;	// print character to screen
  }

Once you have created a file stream and attached it to a file, it's easy to use!  Use an ofstream object just like you would use cout!  Use an ifstream object just like you would use cin.  Examples:

Instead of:        cout << x << "Hello World" << y;
we have:      out1 << x << "Hello World" << y;

Instead of:    cin >> x >> y >> z;
we have:     in1 >> x >> y >> z;

Instead of:    cin.getline(sentence,10,'.');
we have:     in1.getline(sentence,10,'.');

Here are some example programs from the examples/fileio directory:

comma.cpp
inputsample.cpp, which can read the files testinput and testinput2
iosample.cpp, which can read the files testinput and testinput2