C programming language did not have the input/output functionalities built within language itself. So, there are no specific keywords like read or write. C compilers rely on external libraries to perform input or output operations such as stdio libray provides printf() an dscanf() library functions. C ++ uses ANSI C standard approach and formalizes IO package i.e. (stdio.h) in libraries such as iostream and fstream.
In C++, files are referred to as flow of streams (data) into and out of programs. Streams are basic data type to handle all input and output (I/O) operations. There are different kinds of streams of data flow for input and output. Each stream is associated with a class, which contains member functions and definitions for dealing with that particular kind of flow.
For example, the stream class represents the input disc files,. Thus each file in C++ is an object of a particular stream class. The most basis types of streams are standard input and output streams.
- istream cin
built-in input stream variable; by default hooked to keyboard - ostream cout
built-in output stream variable; by default hooked to console
Both of these classes are defined in header file
<iostream>
.
C++ also supports all the input/output mechanisms that the C language included including file handling. However, C++ streams provide all the input/output capabilities of C, with substantial Improvements. We will exclusively use streams for input and output of data. C++ also provides stream types for reading from and writing to files stored on disk. For the most part, these operate in exactly the same way as the standard I/O streams, cin and cout.
For basic file I/O:
#include <fstream>
C++ provides the following stream classes, as part of C++ standard library, to perform output and input of characters to/from files:
- ofstream: Stream class to write on files
- ifstream: Stream class to read from files
- fstream: Stream class to both read and write from/to files.
There are no pre-defined file stream variables just like input/output streams (cin and cout), so a programmer who needs to use file streams must declare file stream variables:
1 2 | ifstream inFi1e; // input file stream object ofstream outFi1e; // output file stream object |
The types
ifstream
and
ofstream
are C++ stream classes designed to be connected to input or output files. File stream objects have all the member functions and manipulators possessed by the standard streams, cin and cout.
What is C++ stream class hierarchy?
The stream classes are arranged in a rather complex hierarchy. You do not need to understand this hierarchy in detail to program basic file I/O, but a brief overview may be helpful. The extraction operator
>>
is a member of istream class and the insertion
<<
operator is a member of ostream class. Both of these classes are derived from the ios class. The cout object is a predefined object of the ostream with assign class. It is in turn derived from ostream class. The classes used for input and output to the video display and keyboard are declared in the header file
iostream.h
, which we have routinely included in all our programs.
Stream classes
The ios class is the base class for the entire I/O hierarchy in C++. It contains many constants and member functions common to input and output operations of all kinds. The istream and ostream classes are derived from ios and are dedicated to input and output respectively Their member functions perform both formatted and unformatted operations. The iostream class is derived from both istream and ostream by multiple inheritance, so that other classes can inherit both of these classes from it. The classes in which we are most interested for file I/O are ifstream for input files ofsteam for output files and fstream for files that will be used for both input and output the ifstream and ofsteam classes are declared in the fstream.h file.
The isteam class contains input functions such as
- getline()
- getine()
- read()
and overloaded extraction operators.
The ostream class contains functions such as
- Put()
- write()
and overloaded insertor.
How to close a file in C++?
When a program is finished with a file, it must close the file using the
close()
member function associated with each file stream variable:
1 2 | outfile.close( ) ; infile.close( ) ; |
Calling
close()
notifies the operating system that your program is done with the file and that the system should flush any related buffers, update file security information,
etc.
It is always best to close files explicitly, (even though by the C++ standard, files are closed automatically whenever the associated file stream variable goes out of scope).
Writing strings into a file using C++
Let us now consider a program which writes strings into a text file.
1 2 3 4 5 6 7 8 9 | //program for writing a string in a file #include <fstream.h> void main() { ofstream outfile("file.txt"); //create a file for output outfile << "This file is created using C++." << endl; outfile << "This file is created using ASCII mode." << endl; outfile << "The title of this article is File Handling in C++" << endl; } |
In the above program, we create an object called outfile, which is a member of the output file stream class. We initialise it to the filename “file.txt”. You can think of outfile as a user-chosen logical name which is associated with the real file on disc called “file.txt”. When our
main()
function ends, outfile goes out of scope. This automatically calls the destructor, which closes the file. It may be noticed that we do not need to close the file explicitly by any close-file command. The insertion operator << is overloaded in ofsteam and works with objects defined from ofstream. Thus, we can use it to output txt to the file. The strings are written in the file “file.txt” in the ASCII mode. One can see it from DOS by giving the type command. The file “file.txt” looks as shown below
1 2 3 | This file is created using C++. This file is created using ASCII mode. The title of this article is File Handling in C++ |
Reading strings from file using C++
The program below illustrates the creation of an object of ifstream class for reading purpose.
1 2 3 4 5 6 7 8 9 10 11 12 13 | #include <fstream.h> void main() { const int max = 80; //size of buffer char buffer[max]; //character buffer ifstream.infile("file.txt") - //create file for input while (infile) //until end-of-file { infile.getline(buffer, max); //read a line of text cout << buffer } } |
We define infile as an ifstream object to input records from the file “file.txt”. The insertion operator does not work here. Instead, we read the text from the file, one line at a time, using the
getline()
function. The
getline()
function reads characters until it encounters the “\n” character. It places the resulting string in the buffer supplied as an argument. The maximum size of the buffer is given as the second argument. The contents of each line are displayed after each line is input. Our ifstream object called infile has a value that can be tested for various error conditions -one is the end-of-file. The program checks for the EOF in the while loop so that it can stop reading after the last string.
What is a buffer in C++?
A buffer is a temporary holding area in memory which acts as an intermediary between a program and a file or other I/0 device. Information can be transferred between a buffer and a file using large chunks of data of the size most efficiently handled by devices like disc drives. Typically, devices like discs transfer information in blocks of bytes, while program often processes information one byte at a time. The buffer helps match these two desperate rates of information transfer. On output, a program first fills the buffer and then transfers the entire block of data to a hard disc, thus clearing the buffer for the next batch of output. C++ handles input by connecting a buffered stream to a program and to its source of input. similarly, C++ handles output by connecting a buffered stream to a program and to its output target.
When we are working with file streams, these are associated to an internal buffer object of type
streambuf
. This buffer acts as an intermediary between the stream and the file stored physically on a drive. For example, with an
ofstream
, each time the member function
put()
is called, the character may be inserted in this intermediate buffer instead of being written directly to the physical file with which the stream is associated.
What is Synchronization?
Once buffer is flushed, the data it contains is written back to the physical medium i.e. the file which is called synchronization and takes place under any of the following situations:
- First of all, if the buffer is full it is automatically synchronized.
- File is closed by calling
close()
function or closed automatically by C++. - Explicitly, with manipulators
flush()
and
endl
. - Explicitly, with member function
sync()
To summarize buffering and synchronization,
sync()
is a member of input streams, all unread characters are cleared from the buffer while
flush()
is a member of output streams and buffered output is passed down to the kernel.
Using put() and get() for writing and reading characters
The
put()
and
get()
functions are also members of ostream and istream. These are used to output and input a single character at a time. The program shown below is intended to illustrate the use of writing one character at a time in a file.
C Program to write characters to a file
This C program writes data to a file character by character by using
put()
function. In this program, the length of the string is found by the
strlen()
function, and the characters are output using put( function in a for loop. This file is also an ASCII file.
1 2 3 4 5 6 7 8 9 10 11 | #include <fstream.h> #include <string.h> void main() { charstr[] = "do unto others as you would be done by"; ofstream outfile("file2.txt"); for (int i = 0; i < strlen(str); i++) { outfile put(str[i]); } } |
C Program to read characters from a file
The program shown below illustrates the reading of characters from a file. The program uses the
get()
and continues to read until eof is reached. Each character read from the file is displayed using
cout
. The contents of file file2.txt created in the previous program will be displayed on the screen.
1 2 3 4 5 6 7 8 9 10 11 | #Include <fstream.h> void main() { char ch; ifstream in file("file2.txt"); while (infile) { infile.get(ch); } cout << ch; } |
Using read() and write() for reading and writing object
The
read()
and
write()
functions are also members of istream and oftream. These are used to read and write data from/to a file. The programs shown below are intended to illustrate the use of writing an object to file and reading the object from file using C++.
How to write an object to a file in C++?
Since C++ is an object-oriented language, it is reasonable to wonder how objects can be written to and read from the file. The program given below is intended to write an object in a file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | //program for writing objects in files #include <fstream.h> class employees { protected: int empno; char name[10]; char dept[5]; char desig[5]; double basic; double deds; public: void getdata(void) { coul << endl << "enter empno"; cin >> empno; cout << endl << "enter empname"; cin >> name; cout << endl << "enter department"; cin >> dept; cout << endl << "enter designation"; cin >> desig; cout << endl << "enter basic pay"; cin >> basic : cout << endl << "enter deds"; cin >> deds; } void main(void) { employees emp; emp.getdata(); ofstream outfile("file3.txt"); outfile.write((char*)&emp, sizeof(emp)); } } |
This program uses a class by name employees and an object by name emp. Data can be written only by the function inside the object. This program creates a binary data file by name file3.txt.The
write()
function is used for writing. The
write()
function requires two arguments, the address of the object to be written, and the size of the object in bytes. We use the size of operator to find the length of the emp object. The address of the object must be cast to type pointer to char.
How to read object from a file in C++
The program given below is intended to read the file created in the above program.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | //program for reading data files #include <istream.h> class employees { protected: int empno; char name[I0]; char dept[5]; char desig[5]; double basic; double deds; public: void showdata(void) { cout << endl << "employeenumber: " << empno; cout << endl << "empname " << name; cout << endl << "department " << dept; cout << endl << "designation " << desig; cout << endl << "basic pay " << basic : cout << endl << "deds " << deds; } void main(void) { employees empl; ifstream infile("file3.txt"); infile.read((char*)&empl, sizeof(empl)); empl.showdata(); } } |
It may be noticed that both
read() and
write()
functions have similar arguments. we must specify the address in which the file input will be placed. We also use size of to indicate the number of bytes to be read from the file.
The sample output looks as shown below:
1 2 3 4 5 6 | employeenumber; 123 empname venkatesa department elec designation prog basic pay 567.89 deds 45.76 |
Binary vs. Text files
You might have noticed that write() was used to output binary values, not just characters. To clarify, let us examine this further. Our emp object contained one int data member, three string data members and two double data members. The total number of bytes occupied by the data members comes to 38. It is as if write() took a mirror image of the bytes of information in memory and copied them directly to disc, without bothering any intervening translation or formatting. By contrast, the character based functions take some liberties with the data. for example, they expand the “\n” character into a carriage return and a line feed before storing it to disk.
For further information on binary and text files, refer to File Handling in C article to understand the concept of binary and text files.