0% found this document useful (0 votes)
18 views

OOP - Chapter 8 Stream Computation for Console and File IO (2)

This document provides an overview of stream computation for console and file input/output in C++. It covers the stream class hierarchy, unformatted and formatted input/output operations, and file handling methods, including the use of ifstream, ofstream, and fstream classes. Key concepts such as opening and closing files, formatting output, and error testing during file operations are also discussed.

Uploaded by

abhiyank40
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
18 views

OOP - Chapter 8 Stream Computation for Console and File IO (2)

This document provides an overview of stream computation for console and file input/output in C++. It covers the stream class hierarchy, unformatted and formatted input/output operations, and file handling methods, including the use of ifstream, ofstream, and fstream classes. Key concepts such as opening and closing files, formatting output, and error testing during file operations are also discussed.

Uploaded by

abhiyank40
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 43

OOP

STREAM COMPUTATION FOR


CONSOLE AND FILE
INPUT/OUTPUT
CHAPTER 8

KABIN DEVKOTA UDITA BISTA


01 Stream Class Hierarchy for Console I/O
02 Testing Stream Errors
TABLE OF
03 Unformatted Input/Output
CONTENTS Formatted I/O with ios Member Function and Flags
04
05 Formatting with Manipulators
06 Stream Operator Overloading
07 File I/O with Streams
08 File Stream Class Hierarchy
09 Opening and Closing Files

10 Read/Write from File


Our content is
divided into the given topics.
11 File Access Pointers and their Manipulators
Each part will be described in the slides
that follow 12 Sequential and Random Access to File
13 Testing Errors during File Operations
STREAM INPUT/OUTPUT
A stream is an interface provided by I/O system to the programmer. A stream, in
general, is a name given to flow of data. In other words, it is a sequence of bytes.
The stream acts either as a source from which the input data can be obtained or as
a destination to which the output data can be sent. The source stream that
provides data to the program is called INPUT stream and the destination stream
that receives output from the program is called OUTPUT stream. Thus, a program
extracts the bytes from an input stream and inserts them into the output stream.

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.

cout.put (‘T’) ; // prints T


cout.put(ch) ; // prints the value of variable ch
cout.put(65) ; // displays a character whose ASCII value is 65 that is A

3. getline() and write():


getline():
The getline( ) function reads a whole line of text that ends with a newline character.
The general syntax is:
cin.getline( line, size) ;
where, line is a variable, size is maximum number of characters to be placed.
Consider the following code:
char name[30] ; string name;
cin.getline(name, 30) getline(cin,name); // in case of variable declared as string
or
cin>>name
If we input the following string from keyboard:
“This is test string”.
cin.getline(name, 30) inputs 29 characters taking white spaces and one left null character. so, it
will take the whole line but in case of cin it takes only “This” as it doesn’t consider white spaces.

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

ios class functions and flags


width( ) - To specify the required field size for displaying an output value

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;

Non-parameterized manipulators Parameterized manipulators


endl: output new line and flush
setw(int n) : equivalent to ios function width()
left: sets ios::left flag of ios::adjustfield
setprecision(int n) : equivalent to ios function precision()
right: sets ios::right flag of ios::adjustfield
setfill(char c) : equivalent to ios function fill()
dec: sets ios::dec flag of ios::basefield
setiosflags(flag) : equivalent to ios function setf()
Hex: sets ios::hex flag of ios::basefield
resetiosflags(flag) : equivalent to ios function unsetf()
Oct: sets ios::oct flag of ios::basefield
showpoint: sets ios::showpoint flag
scientific: sets ios::scientific flag of ios::floatfield
fixed: sets ios::fixed flag of ios::floatfield
FILE INPUT/OUTPUT WITH STREAMS
All the programs presented so far take input from standard input device(normally keyboard)
and output displayed on standard output device(normally monitor). The console stream
objects like cout and cin have been used for output and input respectively. However, many
applications may require a large amount of data to be read, processed, and also saved for
later use. In order to handle such a huge volume of data, we need to use some devices such
as floppy disks or hard disks to store the data. The data is stored in these devices using the
concept of files. A file is a collection of related data stored in a particular area on the disk.
Programs can be designed to perform the read and write operations on these files.

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.

Opening Files using Constructor:


We know that a constructor is used to initialize an object while it is being created.
Here, a filename is used to initialize the file stream object. This involves the following steps:
1. Create a file stream object to manage the stream using the appropriate class.(.i.e. If we are writing
to a file we create an object of class ofstream and if we are reading from the file, we create an
object of the class ifstream).
2. Initialize the file object with the desired filename.

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”.

string str = “hello”;


fout<<str; // writes str to the file database attached to fout.

2. Sequential input and output operations:


a) put():
The function put() writes a single character to the associated output file stream.
READ/WRITE FROM FILE
#include<iostream>
#include<fstream>
#include<string.h>
using namespace std;
int main()
{
char text[] = “A test program for put() function.”;
ofstream fout(“hello”); // create and open a file named hello for write operation
for( int i = 0 ; i< strlen(text) ; i++) //loop for each character
{
fout.put(text[i]); // writing each character to file using put() function;
}
}

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);

//closing the file


file.close();
return 0;
}
READ/WRITE FROM FILE
In the above program, the statement
file.open("test.bin", ios::binary);
opens binary file “test.bin” for writing in the binary mode
And the statements,
file.write(name, sizeof(name));
file.write((char*)(&age), sizeof(age));
file.write((char*)(&salary), sizeof(salary));
writes the values of variables name, age and salary to the disk file “test.bin”. The first argument
write() function is the pointer to the character which must take the address of the character
variable. Hence, in this program, the address of the integer variable age and float variable salary
must be casted to type char*.

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.

#include <iostream> fout<< “is” ;


#include <conio.h> int p=fout.tellp( ) ;
#include <fstream> cout<<p ;
using namespace std; fout.close( ) ;
int main( ) getch( ) ;
{ }
ofstream fout(“Test.txt”) ;
fout<< “I am Ram” ; Output:
fout.seekp(3) ; 5
FILE ACCESS POINTERS AND THEIR MANIPULATORS
seekp( ) and seekg( ) can also be used with two arguments as follows:
seekg (offset, refposition) ;
seekp (offset, refposition) ;
Here, the parameter offset represents the number of bytes the file pointer is to be moved from the
location specified by the parameter refpoisition. The refposition takes one of the following three
constants defined in the ios class:
ios::beg start of the file
ios:: cur current position of the pointer
ios::end end of the file
NOTE: If we don’t provide the value of refposition, then the default value will be ios::beg

The offset can also be negative as follows:


file.seekg (-5, ios: : cur) ;
This statement means the file pointer moves five bytes back from the current position.
file.seekg(0, ios: : beg) ; go to start
fout.seekg(0, ios: : cur) ; stay at current position
fout.seekg(0, ios: : end) ; go to end

Similarly, all above concepts are same for seekp( ) ;


FILE ACCESS POINTERS AND THEIR MANIPULATORS
FOR EXAMPLE:

fstream fout(“abc.txt”,ios::in|ios::out); h e l l o w o r l d EOF


fout<<”hello world”;
0 1 2 3 4 5 6 7 8 9 10 11
int a = fout.tellp();
cout<<a<<endl;
fout.seekp(6); h e l l o w o r l d EOF
fout<<”##”;
0 1 2 3 4 5 6 7 8 9 10 11
fout.seekp(-4,ios::cur);
char ch = fout.get();
cout<<ch; h e l l o # # r l d EOF

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

You might also like