Chapter Four
Chapter Four
C++ has support both for input and output with files through the following classes:
▪ fstream: File class for both reading and writing operations (derived from iostream)
4.1.Open a file
The first operation generally done on an object of one of these classes is to associate it to a real
file, that is to say, to open a file. The open file is represented within the program by a stream object
(an instantiation of one of these classes) and any input or output performed on this stream object
will be applied to the physical file.
In order to open a file with a stream object we use its member function open():
where filename is a string of characters representing the name of the file to be opened and mode
is a combination of the following flags:
These flags can be combined using bitwise operator OR: |. For example, if we want to open the
file "example.bin" in binary mode to add data we could do it by the following call to function-
member open:
ofstream file;
file.open ("example.bin", ios::out | ios::app | ios::binary);
All of the member functions open of classes ofstream, ifstream and fstream include a default mode
when opening files that varies from one to the other:
ifstream ios::in
The default value is only applied if the function is called without specifying a mode parameter. If
the function is called with any value in that parameter the default mode is stepped on, not
combined.
Since the first task that is performed on an object of classes ofstream, ifstream and fstream is
frequently to open a file, these three classes include a constructor that directly calls the open
member function and has the same parameters as this. This way, we could also have declared the
previous object and conducted the same opening operation just by writing:
You can check if a file has been correctly opened by calling the member function is_open():
bool is_open();
that returns a bool type value indicating true in case that indeed the object has been correctly
associated with an open file or false otherwise.
4.2.Closing a file
When reading, writing or consulting operations on a file are complete we must close it so that it
becomes available again. In order to do that we shall call the member function close(), that is in
charge of flushing the buffers and closing the file. Its form is quite simple:
void close ();
Once this member function is called, the stream object can be used to open another file, and the
file is available again to be opened by other processes.
In case that an object is destructed while still associated with an open file, the destructor
automatically calls the member function close.
Generally, when using text files we shall use the same members of these classes that we used in
communication with the console (cin and cout). As in the following example, where we use the
overloaded insertion operator <<:
examplefile.close();
return 0;
}
Data input from file can also be performed in the same way that we did with cin:
#include <fstream.h>
#include <stdlib.h>
int main () {
char buffer[256];
if (! examplefile.is_open())
while (! examplefile.eof() )
examplefile.getline (buffer,100);
return 0;
This last example reads a text file and prints out its content on the screen. Notice how we have
used a new member function, called eof that ifstream inherits from class ios and that returns true
in case that the end of the file has been reached.
bad()
Returns true if a failure occurs in a reading or writing operation. For example in case we try to
write to a file that is not open for writing or if the device where we try to write has no space left.
fail()
Returns true in the same cases as bad() plus in case that a format error happens, as trying to read
an integer number and an alphabetical character is received.
eof()
Returns true if a file opened for reading has reached the end.
good()
It is the most generic: returns false in the same cases in which calling any of the previous functions
would return true.
In order to reset the state flags checked by the previous member functions you can use member
function clear(), with no parameters.
ifstream, like istream, has a pointer known as get pointer that points to the next element to be read.
ofstream, like ostream, has a pointer put pointer that points to the location where the next element
has to be written.
These stream pointers that point to the reading or writing locations within a stream can be read
and/or manipulated using the following member functions:
These two member functions admit no parameters and return a value of type pos_type (according
ANSI-C++ standard) that is an integer data type representing the current position of get stream
pointer (in case of tellg) or put stream pointer (in case of tellp).
This pair of functions serve respectively to change the position of stream pointers get and put. Both
functions are overloaded with two different prototypes:
seekg (pos_type position);
seekp ( pos_type position );
Using this prototype the stream pointer is changed to an absolute position from the beginning of
the file. The type required is the same as that returned by functions tellg and tellp.
Using this prototype, an offset from a concrete point determined by parameter direction can be
specified. It can be:
ios::cur offset specified from the current position of the stream pointer
The values of both stream pointers get and put are counted in different ways for text files than for
binary files, since in text mode files some modifications to the appearance of some special
characters can occur. For that reason it is advisable to use only the first prototype of seekg and
seekp with files opened in text mode and always use non-modified values returned by tellg or tellp.
With binary files, you can freely use all the implementations for these functions. They should not
have any unexpected behavior.
The following example uses the member functions just seen to obtain the size of a binary file:
// obtaining file size size of example.txt is 40 bytes.
#include <iostream.h>
#include <fstream.h>
int main () {
long i,m;
i= file.tellg();
m = file.tellg();
file.close();
return 0;
4.6.Binary files
In binary files inputting and outputting data with operators like << and >> and functions like
getline, does not make too much sense, although they are perfectly valid.
File streams include two member functions specially designed for input and output of data
sequentially: write and read. The first one (write) is a member function of ostream, also inherited
by ofstream. And read is member function of istream and it is inherited by ifstream. Objects of
class fstream have both. Their prototypes are:
#include <iostream.h>
#include <fstream.h>
int main () {
char * buffer;
long size;
size = file.tellg();
file.close();
delete[] buffer;
return 0;
Exercise
1. Write a program which outputs its own C++ source file to the screen.
2. Write a program that counts and displays the number of characters (including blanks) in
its own source code file.
3. Without using an array, write a program that prints itself out backwards on the screen.
4. Write a function that takes two file names as argument and returns true ( 1 ) if the content
of the two files are identically the same, else returns false ( 0 ) and write a main function
that implements this function
5. What screen output does the following program produce, and why?
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
char character;
int integer;
ofstream out_stream;
ifstream in_stream;
/* Create a file containing two integers */
out_stream.open("Integers");
out_stream << 123 << ' ' << 456;
out_stream.close();
/* Attempt to read a character, then an integer,
then a character again, then an integer again,
from the file "Integers" just created. */
in_stream.open("Integers");
in_stream >> character >> integer;
cout << "character: '" << character << "'\n";
cout << "integer: " << integer << "\n";
in_stream >> character >> integer;
cout << "character: '" << character << "'\n";
cout << "integer: " << integer << "\n";
in_stream.close();
return 0;
}