logo

Reading Data From Files Using C ++

Note: This material is adapted from chapters 11 and 14 of "C++: How to Program" by Deitel and Deitel.

Data is stored in files so that it may be retrieved for processing when needed. The commands for reading data from a file are (for the most part) very similar to those used to read data from the keyboard. However, some important distinctions are described here.

In order for your program to read from the file, you must:

  • include the fstream header file with using std::ifstream;
  • declare a variable of type ifstream
  • open the file
  • check for an open file error
  • read from the file
  • after each read, check for end-of-file using the eof() member function
  • close the file when access is no longer needed (optional, but a good practice)
#include <iostream>
using std::cerr;
using std::cout;
using std::endl;
#include <fstream>
using std::ifstream;
#include <cstdlib> // for exit function
// This program reads values from the file 'example.dat'
// and echoes them to the display until a negative value
// is read.
int main()
{
   ifstream indata; // indata is like cin
   int num; // variable for input value
indata.open("example.dat"); // opens the file
   if(!indata) { // file couldn't be opened
      cerr << "Error: file could not be opened" << endl;
      exit(1);
   }
indata >> num;
   while ( !indata.eof() ) { // keep reading until end-of-file
      cout << "The next number is " << num << endl;
      indata >> num; // sets EOF flag if no value found
   }
   indata.close();
   cout << "End-of-file reached.." << endl;
   return 0;
}

In this example, the variable indata is declared as type ifstream. It is used in the same way that cin is used for doing input from the keyboard. The statement indata >> num; reads characters from the file and converts them to a data value of the appropriate type-in this case integer. In doing so, whitespace characters are skipped over; the same action takes place in the case of reading into a variable of type char, float or double. (Whitespace characters include space, tab, newline). Several values my be read using the same input statement. For example: indata >> num1 >> num2 >> num3;

When opening a file, you should always check for success before continuing. The ! operator for the filename returns true if the file can't be opened. The value of indata.eof() is true if the most recent attempt to read a value was unsuccessful (i.e. no more data).

The following example shows how to read one character at a time.

char letter; // variable for input value
indata >> letter;
while ( letter != 'Q' ) {
cout << letter;
indata >> letter;
}
cout << endl;

INPUT: ab 12 3Q
OUTPUT: ab123

The above example reads and echoes characters from the file until the letter Q is encountered, at which point the program stops. Note that the spaces (whitespace) are skipped over and do not appear in the output-only 6 characters are actually read.

The next example shows how to read an entire string using the >> operator.

char word[10]; // variable for input value
indata >> word;
cout << word << endl;

INPUT1: ab123 5670 sdQzx | INPUT2: abcdefghijklmnop qrstuvwxyz
OUTPUT1: ab123 | OUTPUT2: ?????????????

When reading character values into a string variable using >> , characters are read until whitespace is encountered. It is the programmer's responsibility to make sure that the string variable is large enough to store all the characters that are read. Thus, for INPUT1, the characters 'ab123' are read and stored in the variable word. The space between the '3' and the '5' terminates the read operation. In the second example, the programmer made a mistake since the string has only space for 10 characters, but the computer would continue reading up to the letter 'p'. The actual output in this situation would depend on the computer used.

In some situations, it is desirable to read an entire line of input, including the whitespace. For example: to read a name such as 'Joe Student' into a single string variable. This can be done using the getline member function.

char word[10]; // variable for input value
indata.getline(word, 10, '\n');
cout << word << end;

INPUT1: abcdefg // entire line is read into word
OUTPUT1: abcdefg

INPUT2: abcdefghiABCDEFGHIJ // first 9 chars are read in
OUTPUT2: adcdefghi

In this example, the getline function will read characters from the file, placing them in the array word, until 9 characters have been read (leaving one space for the NULL character) or until the delimiter '\n' is read. If there are more than 9 characters on the line, then those 'extra' characters remain in the input buffer. If there are 8 or fewer characters, the whole line is read in and the delimiter is removed from the buffer. Note that if there are exactly 9 characters, then the delimiter is not removed from the buffer.

The peek() function is used to read one character from the input stream while leaving the character in the buffer. The character will be read with the next input statement. The putback() function is used to return the character most recently read to the input stream.