The fstream library discussed in this section is included in compilers previous to the ANSI-C++ standard. The specifications of this standard have introduced some changes on the traditional implementation of this library that have been followed (although simplified) in the processing of this document. |
C++ incorporates support for input and output with files through the following classes:
In order to open a file it is used the member function open():
void open (const char * filename, openmode mode);
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:
ios::in |
Open file for reading |
ios::out |
Open file for writing |
ios::ate |
Incial position: end of file |
ios::app |
Every output is appended at the end of file |
ios::trunc |
If the file already existed it is erased |
ios::binary |
Binary mode |
ofstream file;
file.open ("example.bin", ios::out | ios::app
| ios::binary);
class | default mode to parameter |
ofstream | ios::out | ios::trunc |
ifstream | ios::in |
fstream | ios::in | ios::out |
Since frequently the first task that is performed on an object of classes ofstream, ifstream and fstream is to open a file, the three include a constructor that calls directly to this member function and that has the same parameters as this one. This way, we could also have declared the previous object and conducted the same opening operation just writing:
ofstream file ("example.bin", ios::out | ios::app | ios::binary);
Both forms to open a file are valid.You can check if a file has been correctly opened by calling to the member function is_open():
bool is_open();
that returns a bool type value indicating true in case that indeed the object is correctly associate with an open file or false if on the opposite it is not.
void close ();
In case that an object is destructed and is still associated to an open file, the destructor will automatically call to member function close.
Generally, with text files they are used the same members of these classes that for the communication with console. Like in the following example, where we use the overloaded insertion operator <<:
// writing on a text file #include <fstream.h> int main () { ofstream examplefile ("example.txt"); if (examplefile.is_open()) { examplefile << "This is a line.\n"; examplefile << "This is another line.\n"; examplefile.close(); } return 0; } |
This is another line. |
Data input from file can also be performed in the same way that with cin:
// reading a text file #include <iostream.h> #include <fstream.h> int main () { char buffer[256]; ifstream examplefile ("example.txt"); if (! examplefile.is_open()) { cout << "Error opening file"; exit (1); } while (! examplefile.eof() ) { examplefile.getline (buffer,100); cout << buffer << endl; } return 0; } |
This is a line. This is another line. |
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.
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:
tellg()
and tellp()
These two member functions do not have any parameter 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).
seekg()
and seekp()
seekg (pos_type position);
seekp (pos_type position);
This prototype serves to change the stream pointer to an absolute position from the beginning of the file. The type required is of the same one than the returned by functions tellg and tellp.
seekg ( off_type offset, seekdir
direction );
seekp ( off_type offset
,
seekdir
direction );
Using this prototype, it can be specified an offset from a concrete point determined by parameter direction, that can be:
ios::beg |
offset specified from the beginning of the stream |
ios::cur |
offset specified from the current position of the stream pointer |
ios::end |
offset specified from the end of the stream |
It is necessary to indicate that the value of the stream pointers get and put is counted in different ways for text files than for binary files, since in text mode files can occur some modifications for the appearance of special characters that depend on the platform. For that reason it is advisable that with the text files you use only the first prototype of seekg and seekp and always using non-modified values returned by tellg or tellp. With binary files use freely all the implementations of these functions. They must 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 #include <iostream.h> #include <fstream.h> const char * filename = "example.txt"; int main () { long l,m; ifstream file (filename, ios::in|ios::binary); l = file.tellg(); file.seekg (0, ios::end); m = file.tellg(); file.close(); cout << "size of " << filename; cout << " is " << (m-l) << " bytes.\n"; return 0; } |
size of example.txt is 40 bytes. |
File streams include two member functions specially thought 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:
write ( char * buffer, streamsize size);
read ( char * buffer, streamsize size);
|
the complete file is in a buffer |
When the buffer is emptied, all data that contains is written to the physic media (if it is an out stream) or simply erased (if it is an in stream). This process is called synchronization and it takes place under any of the following circumstances: