File Input/Output

File Streams

Standard streams are automatically opened. Other files must be opened explicitly. Files can be input streams (ifstream), output streams (ofstream), or either/both (fstream).

#include <fstream>

or

#include <ofstream>
#include <ifstream>

as needed.

Open

First a stream object must be declared.

  ifstream input;

Then the stream can be attached to a named file

  input.open(inFileName);

This assumes the file exists and is opened for reading only.

For output use

  ofstream output;
  output.open(outFileName);

This file will be emptied if it exists or created if it does not exist, and will be opened in write-only mode.

To open read/write use

   fstream myfile;
   myfile.open(myfileName);

Modifiers

We can control the characteristics of the file with modifiers

  • ios::in open for input (read). Default for ifstream.
  • ios::out open for output (write). Default for ofstream.
  • ios::binary open as binary (not text)
  • ios::app append
  • ios::trunc if file exists, overwrite (default for ofstream)

Use a pipe (|) to combine them

   ofstream myfile;
   myfile.open("myfile.dat",ios::binary | ios::app);

Inquiring

All inquiry methods return a bool (Boolean). To check whether a file is open

   myfile.is_open()

To check whether a file opened for reading is at the end

   myfile.eof()

To test for any error condition

   myfile.good()

Close

Much of the time, it is not necessary to close a file explicitly. Files are automatically closed when execution terminates. If many files are opened, it is good practice to close them before the end of the run.

   myfile.close();

Rewind

An open unit can be rewound. This places the file pointer back to the beginning of the file. The default is to rewind a file automatically when it is closed.

These are C-style functions and are in <cstdio>.

   rewind(mystream)

You can also seek to position 0

   fseek(mystream,0,SEEK_SET)

where rewind clears the end-of-file and error indicators, whereas fseek does not.

Writing to a File

We write to a file much like to a standard stream. In this example, we assume that var1, var2, and var3 are arrays or vectors of length nlines.

  ofstream out("outfile.txt");
  out<<"column1,column2,column3\n";
  for (int i=0;i<nlines;++i) {
      out<<var1[i]<<","<<var2[i]<<","<<var3[i]<<"\n';
  }

Reading from a File

The extraction operator works on file objects as well as on cin:

#include <fstream>
#include <iostream>

int main() {

  float var1, var2;
  std::ifstream myfile("data.txt");
  if (myfile.is_open()) {
      while ( ! myfile.eof() ) {
          myfile >> var1 >> var2;
          std::cout<<var1<<" "<<var2<<"\n";
     }
  }
}
      


Although this method works, it has a number of drawbacks. As we learned for console IO, the extraction operator assumes the separator is whitespace. It can be thrown off when attempting to convert a string into a numerical type. It also is inflexible. We will discuss more advanced methods in the next chapter.

Exercise

Write a program that creates a file mydata.txt containing four rows consisting of

1 2 3
4 5 6
7 8 9
10 11 12

Either rewind or reopen the file and read the data back. Write a loop to add 1 to each value and print each row to the console. Note that if you choose to rewind, the file will have to be opened read/write. If you close it and reopen it, it will have to be reopened in write mode. You may use a statically-sized array for the data. In the next chapter we will learn a more flexible method of reading lines of files.

Example Solution

#include <iostream>
#include <fstream>

using namespace std;

int main() {
    fstream myfile;
    myfile.open("mydata.txt", ios::out);

    for (int i=1; i<=12; ++i) {
        myfile << i;
        if (i%3==0) {
            myfile << "\n";
        } else {
            myfile << " ";
        }
    }
    myfile.close();

    myfile.open("mydata.txt", ios::in);

    int x[4][3];
    if (myfile.is_open()) {
        for (int i=0; i<4; ++i) {
	    myfile>>x[i][0]>>x[i][1]>>x[i][2];
        }
    } else {
        cout<<"Unable to open file";
        return 1;
    }

    for (int i=0; i<4; ++i) {
	for (int j=0; j<3; ++j) {
            x[i][j]++;
	}
    }
    for (int i=0; i<4; ++i) {
	for (int j=0; j<3; ++j) {
            cout << x[i][j] << " ";
        }
        cout << "\n";
    }
}

Previous
Next