OOP - Chapter 8 Stream Computation for Console and File IO (2)
OOP - Chapter 8 Stream Computation for Console and File IO (2)
Different input devices like keyboard can send data to the input stream. Also, data
in the output stream can go to the output device like screen (monitor) or any other
storage device. In C++, there are predefined I/O stream like cin and cout which are
automatically opened where a program begins its execution.
STREAM INPUT/OUTPUT
STREAM CLASS HIERARCHY FOR CONSOLE I/O
The given figure shows a hierarchy of
stream classes in C++ used to define
various stream in order to deal with
both the console and disk files. From
the figure, it is clear that ios is a base
class. This ios class is declared as
virtual base class so that only one copy
of its members is inherited by its
derived classes ; thereby avoiding
ambiguity.
The ios class comprises basic functions and constants required for input and output
operations. It also comprises functions related with flag strings.
STREAM CLASS HIERARCHY FOR CONSOLE I/O
istream and ostream classes are derived from ios and are dedicated to input and
output streams respectively. Their member functions perform both formatted and
unformatted operations. istream contains functions like get( ), getline, read( ) and
overloaded extraction(>>) operators. ostream comprises functions like put( ), write( )
and overloaded insertion(<<) operators.
The iostream class is derived from istream and ostream using multiple inheritance.
Thus, it provides the facilities for handling both input and output streams. The class
istream_withassign and ostream_withassign add assignment operator to these classes.
Again the classes ifstream and ofstream are concerned with file I/O function. ifstream
is used for input files and ofstream for output files. Also there is another class of
stream which will be used both for input and output. All the classes ifstream, ofstream
and fstream are derived from classes istream, ostream and iostream respectively.
streambuf is also derived from ios base class. filebuf is derived from streambuf. It is
used to set the file buffers to read and write. It also contains open( ) and close( ) used
to open and close the file respectively.
UNFORMATTED INPUT/OUTPUT
1. Overloaded Operators >> and <<:
The general format for reading data from keyboard is :
cin>>var1>>var2>>......>>varn.
This statement will cause the computer to stop the execution and look for input
data from the keyboard. While entering the data from the keyboard, the
whitespace, newline and tabs will be skipped. The operator >> reads the data
character by character basis and assigns it to the indicated locations. Again, the
general format for displaying data on the computer screen is :
cout<<item1<<item2<<...........<<itemn;
Here, item1, item2, ......., itemn may be character or variable of any built-in data
type.
2. get() and put():
These are another kind of input/output functions defined in classes istream and ostream to
perform single character input/output operations.
get():
There are 2 types of get functions i.e. get(char*) and get(void) which help to fetch a character
including the blank space, tab and a new line character. get( char ) assigns input character to its
argument and get(void) returns the input character.
char c;
cin.get(c) ; // obtain single character from keyboard and assign it to char c
OR
c=cin.get( ) ;
OR
cin>>c ; // this will skip white spaces, tabs, and newline
put():
It is used to output a line of text character by character basis.
Example:
#include <iostream> Output:
using namespace std; First Run:
int main( ) Enter city name: Kathmandu
{ City name : Kathmandu
char city[20] ; Enter city name again : Lalitpur
cout<< “Enter city name:\n” ; New city name : Lalitpur
cin>>city ;
cout<< “city name:”<<city<<”\n\n” ; Second Run:
cout<< “Enter city name again:\n” ; Enter city name : New Baneshwor
cin.getline (city, 20) ; City name : New
cout<< “New city name:”<<city<< “\n\n” ; Enter city name again : Old Baneshwor
} New city name : Old Baneshwor
write():
This function displays an entire line of text in the output string.
The general syntax is:
cout.write(line, size)
where, line represents the name of string to be displayed and second argument size indicates
number of characters to be displayed.
#include <iostream>
using namespace std;
int main( ) Output:
{ HELLO WELCOME TO KEC
Char str[30] = “HELLO WELCOME TO KEC”; HELLO WE
cout.write(str, 30);
cout.write( str, 8);
}
FORMATTED INPUT/OUTPUT
C++ supports a number of features that could be used for formatting the output. These features
include
ios class functions and flags
manipulators
Precision( ) - To specify the no. of digits to be displayed before and after a decimal point of a
float value.
fill( ) - To specify a character that is used to fill the unused portion of a field
setf( ) - To specify format flags that can control the form of output display (such as left- left-
justification and right-justification)
unsetf( ) - To clear flags specified
FORMATTED INPUT/OUTPUT
1. width():
This function of ios class is used to define the width of the field to be used while displaying
the output. It is normally accessed with a cout object. It has the following form:
cout.width(6); //sets field width to 6
Example: The value 849 is printed right-justified in the first six columns. The
cout.width(6); specification width(6) does not retain the setting for printing the
cout<<849<<endl; number 45. This can be improved as follows:
cout<<45<<endl; cout.width(6);
cout<<849<<endl;
Output: cout.width(6);
_ _ _849 cout<<45<<endl;
45
Output:
---849
----45
FORMATTED INPUT/OUTPUT
2. fill():
This ios function is used to specify the character to be displayed in the unused portion of the
display width. By default, blank characters are displayed in the unused portion.
Syntax:
cout.fill(ch);
where ch is a character used to fill the unused space
Example:
int x = 456;
cout.width(6);
cout.fill(‘#’);
cout<<x<<endl;
Output:
###456
FORMATTED INPUT/OUTPUT
3. precision():
This function belonging to ios class is used to specify maximum number of digits to be displayed
as a while in floating point number or the maximum number of digits to be displayed in the
fractional part of the floating point number. In general format, it specifies the maximum number of
digits including fractional or integer parts. This is because in general format the system chooses
either exponential or normal floating point format which best preserves the value in the space
available.
cout.precision(4);
Example:
float x=5.5005, y=66.769;
cout.precision(3);
cout<<x<<endl;
cout<<y<<endl;
Output:
5.5
66.8
FORMATTED INPUT/OUTPUT
4. setf():
The ios member function setf() is used to set flags and bit fields that controls the output in
other ways.
cout.setf(flag_value, bit_field_value);
Example:
int x = 456; Flag_value bit_field_value
float y = 123.45;
cout.setf(ios::left, ios::adjustfield); ios::left
cout.width(6); ios::right ios::adjustfiled
ios::internal
cout.fill(‘#’);
cout<<x<<endl; ios::scientific ios::floatfield
ios::fixed
cout.setf(ios::scientific, ios::floatfield);
cout<<y<<endl
ios::dec ios::basefield
ios::oct
Output: ios::hex
456###
1.234500e+02
FORMATTING WITH MANIPULATORS
The header file “iomanip” provides a set of functions called ‘manipulators’ which can be used
to manipulate the output formats. They provide the same features as that of the ios member
functions and flags.
We can use two or more manipulators as a chain in one statement
cout<<manip1<<manip2<<item;
cout<<manip1<<manip2<<item<<manip3;
A program typically involves either or both the following kinds of data communication:
1. Data transfer between the console unit and the program
2. Data transfer between the program and a disk file.
FILE INPUT/OUTPUT WITH STREAMS
FILE INPUT/OUTPUT WITH STREAMS
File Stream
The I/O system of C++ handles file operations which are very much similar to the console
input and output operations. A file stream is an interface between the programs and the files.
The stream which supplies data to the program is called input stream and that which receives
data from the program is called output stream i.e. the input stream reads or receives data
from the file and supplies it to the program while the output stream writes or inserts data to
the file.
FILE INPUT/OUTPUT WITH STREAMS
Class Hierarchy for File Stream
FILE INPUT/OUTPUT WITH STREAMS
Class Hierarchy for File Stream
The I/O system of C++ contains a set of classes that define the file handling methods. These include
ifstream, ofstream and fstream. These classes are derived from fstreambase and from the
corresponding iostream class as shown in figure. These classes, designed to manage the disk files,
are declared in fstream and therefore we must include this file in any program that uses files.
ios: It stands for input output stream. This class is the base class for other classes in this class
hierarchy. This class contains the necessary facilities that are used by all the other derived classes
for input and output operations.
istream: istream stands for input stream. This class is derived from the class ‘ios’. This class handles
input stream. The extraction operator(>>) is overloaded in this class to handle input operations from
files to the program. This class declared input functions such as get(), getline() and read().
ostream: ostream stands for output stream. This class is derived from the class ‘ios’. This class
handles output stream.The insertion operator(<<) is overloaded in this class to handle output
streams to files from the program. This class declares output functions such as put() and write().
Class Hierarchy for File Stream
streambuf: This class contains a pointer which points to the buffer which is used to manage the
input and output streams.
fstreambase: This class provides operations common to the file streams. Serves as a base for
fstream, ifstream and ofstream class. This class contains open() and close() function.
ifstream: This class provides input operations. It contains an open() function with default input
mode. It inherits the functions get(), getline(), read(), seekg() and tellg() functions from the istream.
ofstream: This class provides output operations. It contains an open() function with default output
mode. It inherits the functions put(), write(), seekp() and tellp() functions from the ostream.
fstream: This class provides support for simultaneous input and output operations.
It inherits all the functions from istream and ostream classes through iostream.
filebuf: Its purpose is to set the file buffers to read and write. We can also use the file buffer
member function to determine the length of the file.
OPENING AND CLOSING FILES
A file can be opened in two ways:
1. Using the constructor function of the class: This method is useful when we use only one file in
the stream.
2. Using the member function open() of the class: This method is used when we want to manage
multiple files using the stream.
For example, the following statement opens a file named results for the output:
ofstream outfile(“results”); //output only
This creates outfile as an object of the class ofstream that manages the output stream. This object can
be any valid c++ name such as o_file, myfile, fout etc. This statement opens a file named “results” and
attaches it to the output stream outfile.
OPENING AND CLOSING FILES
Opening Files using open():
As stated earlier, the function open() can be used to open multiple files that use the same stream
object. For example,, we may want to process a set of file sequentially. In such cases, we may create
a single stream object and use it to open each file in turn. This is done as follows:
file-stream-class stream-object;
stream-object.open(“Filename);
Example:
ofstream outfile; //create stream(for output)
outfile.open(“Data1”); //connect output stream (outfile) to Data1 File.
………….
outfile.close(); //disconnect output stream(outfile) from Data1 File
outfile.open(“Data2”); //connect output stream (outfile) to Data2 File.
………….
outfile.close(); //disconnect output stream(outfile) from Data2 File
………….
OPENING AND CLOSING FILES
Opening Files using open():
Here, we are opening the file Data1 and Data2 using the object “outfile” of the ofstream class. This
means that we are only allowed to perform write operations in multiple files using the same output
stream object “outfile”.
Suppose we want to perform both reading and writing operations on the same file, then we need to
create an object of fstream class.
This is done as follows:
fstream finout;
finout.open(“file_name”,”opening_mode”);
OPENING AND CLOSING FILES
Opening Files using open():
File opening modes can be on of the following:
ios: : in This mode opens a file for reading. (Default for istream). The file open will be unsuccessful if we try to open a non-existing
(input) file.
ios: : out This mode opens a file for writing. (default for ofstream) . When a file is opened in this mode, it also opens in the ios::trunc
(output) mode by default. If specified already exists, it is truncated to zero length otherwise a new file will be created.
ios::app When a file is opened in this mode, the file is opened in the write mode with the file access pointer at the end of the file. This
(append) mode can be used only with output files.
ios: : binary When a file is opened in this mode, the file is opened as a binary file and not as an ASCII text file.
ios: : ate When a file is opened in this mode, a file access pointer is set at the end of the file. The ios::ate is usually compiled with ios::in
(at the end) or ios::out for reading and writing.
ios: : trunc
When a file is opened in this mode, the file is truncated to zero length if a file specified already exists.
(truncate)
READ/WRITE FROM FILE
1. Insertion operator(<<) and Extraction Operator (>>):
Like console input and output, insertion and extraction operators can also be used for the input and
output operation in a file.
ofstream fout(“database”);
It creates fout as an object of the class ofstream and binds the fout object with the file
named“database”.
b) get():
The function get() reads a single character from the associated input file stream.
READ/WRITE FROM FILE
#include<iostream>
#include<fstream>
using namespace std;
int main()
{
ifstream infile("hello");
char ch;
while(1)
{
ch = infile.get();
if(infile.eof() == 1)
{
break;
}
cout<<ch;
}
return 0;
}
READ/WRITE FROM FILE
3. write() and read() functions
Machines use binary format to store the information rather than ASCII format. In many cases, binary
format saves disk space and makes storing and retrieval faster. To store and retrieve binary data,
member functions write() and read() of ifstream and ofstream are used respectively.
write():
The write() member function is used to binary the information in a binary file. The write() is used as
follows:
file_obj.write((char *)&variable , sizeof(variable));
write() function takes two arguments:
The first is the address of the variable (The address of variable must be cast to type (char *) i.e.
pointer to character type.)
The second is the size of the variable
READ/WRITE FROM FILE
//reading input from the user
#include<iostream>
cout<<"Enter name: ";
#include<fstream>
cin>>name;
using namespace std;
cout<<"Enter age: ";
int main()
cin>>age;
{
cout<<"Enter salary: ";
ofstream file;
cin>>salary;
char name[20];
int age;
//writing the information to the binary file using write()
float salary;
file.write(name, sizeof(name));
file.write((char*)(&age), sizeof(age));
//opening a binary file in output mode
file.write((char*)(&salary), sizeof(salary));
file.open("test.bin", ios::binary);
read():
The read() member function is used to binary the information in a binary file. The read() is used as
follows:
file_obj.read((char *)&variable , sizeof(variable));
READ/WRITE FROM FILE
Likewise write() function, read() function also takes two arguments:
The first is the address of the variable ( The address of variable must be cast to type (char *) i.e.
pointer to character type.
The Second is the size of the variable
//reading the information from the
#include<iostream> //opening a binary file in output mode binary file using read()
#include<fstream> file.open("test.bin", ios::binary|ios::out); file.read(name1, sizeof(name1));
using namespace std; file.read((char*)(&age1), sizeof(age1));
int main() //writing information to binary file using write() file.read((char*)(marks1), sizeof(marks1));
{ file.write(name, sizeof(name));
fstream file; file.write((char*)(&age), sizeof(age)); cout<<"Name:"<<name1<<endl;
char name[20] = "Jack"; file.write((char*)(marks), sizeof(marks)); cout<<"Age:"<<age1<<endl;
int age = 35; cout<<"Marks:"<<endl;
float marks[4] = {23,78,56,34}; //closing the file for(int i=0;i<4;i++)
file.close(); {
char name1[20]; cout<<marks1[i]<<endl;
int age1; //opening a binary file in input mode }
float marks1[5]; file.open("test.bin", ios::binary|ios::in); file.close();
return 0;
}
FILE ACCESS POINTERS AND THEIR MANIPULATORS
Each file has two associated pointers known as file pointers. One of them is called input
pointer(or get pointer) and the other is called the output pointer(or put pointer). The input
pointer is used for reading the contents of a given file location and the output pointer is used
for writing to a given file location.
When input and output operation takes place, the appropriate pointer is automatically set
according to mode. For example, when we open a file in reading mode get file pointer is
automatically set to the start of file. And when we open in append mode the put file pointer is
automatically set at the end of file.
In C++ there are some manipulators by which we can control the movement of pointer. The
available manipulators in C++ are:
1. seekg( ): Moves get pointer(input) to a specified location.
2. seekp( ): Moves put pointer(output) to a specified location.
3. tellg( ): Gives the current position of the get pointer.
4. tellp( ): Gives the current position of the put pointer.
FILE ACCESS POINTERS AND THEIR MANIPULATORS
For Example,
ifstream infile;
infile.open(“test.txt”);
infile.seekg(10);
Moves the input file pointer to the byte number 10. Remember, the bytes in a file are numbered
beginning from zero. Therefore, the pointer will be pointing to the 11th byte in the file.
0 1 2 3 4 5 6 7 8 9 10 11
Output:
11
o h e l l o # # r l d EOF
0 1 2 3 4 5 6 7 8 9 10 11
TESTING ERRORS DURING FILE OPERATION
So far we have been opening and using the files for reading and writing on assumption that
everything is fine with the files. This may not always be true. There are many situations where errors
may occur during file operations. These errors must be detected and appropriate action must be
taken to prevent it. Some functions that can be used to detect errors are:
1. is_open():
Returns non-zero value if the file is opened successfully else returns zero value.
ofstream outfile(“hello.txt”);
if(outfile.is_open())
{
//file is opened successfully
}
else
{
//file cannot be opened..
}
TESTING ERRORS DURING FILE OPERATION
2. eof():
Returns non-zero if end of file is reached otherwise returns zero value.
ifstream fin(“abc.txt”);
while(! fin.eof())
{
char ch = fin.get();
cout<<ch;
}
else
{
//end of file is reached
}
The above program reads individual characters from the file and prints on the screen until the end
of file is reached.
TESTING ERRORS DURING FILE OPERATION
3. fail():
Returns true if input or output operation has failed.
ofstream o_file(“hello.txt”) ;
o_file<<”I am writing on the file”;
if( o_file.fail())
{
cerr<<”can’t write on the file”; //cerr is used to print error message on console(monitor)
}
4. bad():
Returns true if an invalid operation is attempted or any unrecoverable error has occurred.
5. good():
Returns true if no error has occurred. If file.good() returns true, then everything is fine and we
can perform input and output operations.
Example
ifstream infile;
infile.open(“ABC”);
while(!infile.fail())
{
//process the file
}
if(infile.eof())
{
//terminate program normally
}
else if(infile.bad())
{
//report fatal error
}
else
{
infile.clear(); //clear error state so further operations can be attempted
}
THANK YOU