<Previous Lesson

Introduction to Programming

Next Lesson>

Lesson#35

Lesson 35

Summary


30) Streams
31) Source and Destination of streams:
32) Formatted Input and Output
33) Recap Streams
34) Buffered Input/Output
35) Methods with streams
36) Examples using streams

 

Streams


We have been discussing the concept of ‘Streams’ from the very beginning of the course.
In this lecture, various aspects of this concept will be discussed. There are two types of
streams i.e. input streams and output streams. Before going into minute details, we will
see what actually these two types are. You are well aware of the terms ‘cin’ and ‘cout’,
used several times in our previous programs. We have used cout for output and cin for
input. Similarly, the terms of file input and file output are very much known to us. We
leaned how to write in files and how to read from files. These are also streams. Let’s have
a look on the things and functions we can do with streams. There are some specific
functions for input and output in C. printf and scanf are normally used in C. In these
functions, we have to tell what type of data we are using and in which variable. Streams
are counterpart of this in C++. The input output system in C++ is streams. As the name
applies, it’s a stream of bytes. As told earlier, it may also be termed as a door through
which program can communicate with the outside world. For entering some data, we use
cin
stream while the data is read from the keyboard and stored in some variable. To
display data on the screen, we can take help of cout.
Page 447
For making the things more comprehensive, we will consider the example of a classroom.
Suppose you are sitting in the class and listening to this lecture. All of a sudden,
the students are asked by the instructor to go out of the classroom. How would you do it?
You will get up from the seat and walk through the door. But you can see that all of you
cannot go through the door simultaneously. You would go through the door one by one.
Similarly if you have to come to the classroom, you will enter one by one and sit on the
seats. In a way you are forming a sequence of people in this case. Stream is a sequence of
bytes. It is an ordered sequence. Let’s compare it with the door example. The person who
enters first will go out of the door first. The person who enters behind someone will go
out behind that person. Similarly streams are also ordered sequence. The thing that enters
first into the stream will go out first. You should think streams as ordered sequence of
bytes. Byte is a unit of measure. A byte can store one character, so you can think of an
ordered sequence of characters.
As programmers, we communicate with our programs in English through the keyboard.
We may be typing the letters, abc or the numbers, 012 on the keyboard. These all are the
characters. In the programs, we store these characters in variables of different data types.
Sometimes, these may be in some of our objects. On the keyboard, we type the character
‘a’ that is stored in some variable c in our program. How these two are linked? This link
is formed in cin stream. Consider cin as a pipe or a door. The character ‘a’ is entered
from one side and then a conversion takes place i.e. character is converted into its binary
representation, stored in the character variable named c. So there is an implicit
conversion happening. The same thing happens, if we have an integer i and press the key
1 from the keyboard. The digit 1 travels as a character but inside it is stored as number.
You have to be careful while dealing with this concept. We have talked about the ASCII
characters. On the keyboard, we have alphabets, numbers and symbols. When you press
the number key from the keyboard, it goes at number inside the computer. In general
terms, it is a character. It means that when you enter a key on your keyboard, a character
sequence is generated that later goes into the computer. This character sequence has some
binary representation. It does not mean a sequence of characters, but a code that goes
inside the computer on pressing a key on the keyboard. This code is called as ASCII
code. It is the binary representation of a character. Here both the characters ‘A’ and ‘B’
have some binary representation. Similarly ‘0’,’1’,’2’ have some binary representation. It
does not mean that the character representation of ‘1’ is also ‘1’. If you are aware of the
ASCII table (you have already written a program to display the ASCII table), it will be
evident that the binary representation of character ‘1’ is some other value. Similarly all
the numbers 1, 2, 3 etc have some ASCII value. So whenever you press any key on the
keyboard, its ASCII code goes inside the computer.
Now when we use cin stream to read some number from the keyboard and store it in the
integer variable, its binary representation is ignored and the value is stored. So cin is
performing this transformation operation. It is taking a character ASCII code and knows
that it is supposed to represent some number. It has the ability to convert it into the
appropriate number before putting it into the integer variable i. What happen if we use cin
to read some value and store it in some integer variable and press some alphabet key
Page 448
instead of numeric keys. Some error will occur. So in the cin stream, an error can be
detected.
Let’s us look at the collection of input and output classes. These are objects having
functions. This collection of classes and their functions are known as input-output
streams in the C++. The most common things that we have been using are cin, used to get
input from the keyboard and cout employed to display something on the screen. So one is
input stream and the other one is output stream. Since we are not going to discuss the
object- oriented programming in this course. We will not discuss the hierarchy through
which these classes are derived. We have some objects for input stream and out put
stream e.g. cin and cout respectively. Being objects, they have member methods that we
can call. They also have the operators like ‘<<’ and ‘>>’, as used in the earlier programs.
These operators ‘<<’, ‘>>’ are heavily overloaded. What does this mean? If we write cin
>> i;
here i is an integer. Automatically cin will take a character in ASCII code from the
keyboard, convert it into number and store it into the integer variable. On the other hand,
if we write cin >> c; where c is a character data type. When we press a key from the
keyboard, it will be stored in c as a character. So the stream extractor operator of cin (i.e.
>>, which gets the data from the stream and stores it into the variable) is already
overloaded. It knows how to behave with int, char, float etc data type and what sort of
conversion is required. In case of float number, we have decimal point, cin knows how to
treat it besides converting and storing it into a float variable. Similarly if we use any
character pointer i.e. string, the same >> operator has the capability of reading strings
too. Obviously, one operator can’t perform all these functions. It seems that we are using
the same operator. Internally, this operator is overloaded. It is not the same for int, char,
float, string and so on. But due to the operator overloading, its usage is very simple. We
just write cin >> i; it works perfectly.

Source and Destination of streams


As earlier said that streams are sort of door or pipe between two things. What are these
two things? For every stream, there must be some source and some destination. For cin,
the source is normally keyboard and the destination can be an ordinary variable i.e.
native-data type variable. It could be some area of memory or our own data type, i.e.
object for which we have overloaded the operator and so on. So always there is a source
and there is a destination.
cout
is output stream. It takes the data from the program and presents it in human
readable form. It also has some source and destination. The source may be some file, or
the region in memory or the processor or a simple variable or our own object of our data
type. The destination is normally screen. The destination can be a file, screen, or printer
etc. You have used file input and file output so you know how it works. When we talk
about area in memory, it may be an array that we read or write. It could also be a
character string which is itself an area in the memory.
“Every stream has an associated source and a destination”
Page 449
Now we will talk about yet another concept i.e. the state of stream. What does it mean?
We say that cin >> i ; where i is an integer. When we give it the input ‘a’ and press the
key ‘enter’, the stream knows that it is a bad input. So it is capable of signaling and
setting its state specifying that some thing not good has been done. So from a program,
we can always test whether the state of stream is right or not. We should carry out all
kinds of error checking, debugging and error handling while writing programs. We don’t
want to manipulate bad data. So checking for this everywhere will be good. For example,
if we write a simple program that takes two integers from key-board, divides one number
by the other and displays the result. Following will be the code segment.
int i, j ;
cin >> i ;
cin >> j ;
cout << i / j ;

Now we have to see what happens if the user gives a value 0 for j. We don’t want to
divide it by zero as even the computer does not know how to do it. When we have zero in
j, our program probably will work through an exception or error before coming to a halt.
If we trap this error inside the program, it would be much nicer. We can say if j is not
zero, it will be good to carry out the division. So error checking and handling is always
important. The same thing applies to I/O streams. When we execute input or output
operation, we should check whether the operation has been carried out correctly or not.
To do this, we can check the state of the stream.
Here is a simple example showing the simple use of streams.
/* Avoiding a precedence problem between the stream-insertion operator and the
conditional operator. */
#include<iostream>
int main()
{
int x,y;
cout<< "Enter two integers: ";
cin>>x>>y;
cout<<x << (x ==y ? " is" : " is not") <<" equal to "<< y;
return 0;
}
The output of the program:
Enter two integers: 3 3
3 is equal to 3
Page 450

Formatted Input and Output


Other things that the streams provide us are a capability of formatted input and output.
We have been using cin and cout very simply without any formatting. As the output of a
program, we do not want that numbers should be printed in a way that makes it difficult
to read and understand. We want to format the output in a way that the numbers are
placed correctly at the correct position on the paper. You might have seen the electricity
bills or telephone bills printed by the computers. First the empty bills are printed in the
printing press containing headings with blank boxes to put in the bill entries. Then the
computer prints the entries in these boxes from the system. These entries (data regarding
the bill) are printed at correct places on the bill. Sometimes, you see that the entries are
properly printed. That is not a computer-fault but only due to poor paper adjustment in
the printer. The printing of these entries is carried out by with the use of formatted output.
The second example is the display of a matrix on the screen. Suppose, we want that the
numbers of a column are displayed up and down in a column. Similarly the second
column should be displayed and so on. At first, we will format these things.
When we do word processing, we type a paragraph. The lines of the paragraph are left
justified but ragged on right hand side. In word processing, we have a choice to justify
the paragraph. By doing this, the left and right margins of the paragraph are put in a
straight line while adjusting the space between the words. Now look what happens if we
want to print a string with cout and want it left or right justified. This is what we call
formatting the output. Similarly, we want to print the value of pi which is stored in a
variable as 3.1415926. But we want that it should be printed as 3.141 that means up to
three decimal places.
There should be a method of formatting it. Thus by formatting the output, the presented
representation (which we read as human being) can be different from the internal
representation. So we can do a lot of formatting with these streams.
Besides, there are member functions with the streams. Let’s look at the member functions
of cin. The first one is the get function. We can use it by writing:
cin.get()
;
The notation explains that cin is an object (cin is an object of input stream) and get is a
member function of it. This function reads a character. In this case, it reads a single
character from key board and returns it as cin is calling it. We have two variants of this
get function with cin. One is that cin.get returns a character. W e can write it as
under:
c = cin.get()
;
The second method is cin.get(character variable) i.e. one character at a time. It works
with characters, not through number or string. It is one character at a time.
Page 451
The second function of cin is the read function. This function differs from the get
function in the way that it returns a buffer instead of a single character. So we can point
to a buffer and tell the number of characters to be read. We normally provide a delimiter,
a specific character up to which we want to read. Normally we use the new line character
as a delimiter and read a single line at a time.
Thus, we have three ways of obtaining input with cin, which is an object of type input
stream (istream). If we create an object of type istream, it will also get these functions as
it is derived from the same class.
We have seen that there are many methods and operators associated with cin. The same
thing applies to cout. cout is the output stream which usually, presents the data from the
computer in human readable form. The operator associated with cout is the stream
insertion (<<). That means we insert the operator in the stream and the stream displays
the output on the screen. So the operator with cout is << and it displays the value of the
data variable that we provide it after the << sign. Thus to display the value of an integer
variable i, we can write cout << i ; If we want to format the output, it can also be done
here.
The cout has a function write with it. This function can be used if we want to write a
chunk of data from the buffer. Similarly, to output a single character, cout has the
function named put. It can be written as:
cout.put(character variable)
;
Here, it will display the value of the character variable.

Recap streams


Streams are nothing but an ordered sequence of bytes.
They allow data to move from one part of the computer to another which may be the
screen or key board from and to, or from memory or files on disc and so on.
Byte stream is used to connect the source and the destination.
These byte streams are implemented as objects. Being objects, they do have their member
functions and have their member operators. The member operators are heavily
overloaded to allow these streams to handle a variety of data types.
The streams have a state that can be checked by us. We have used eof (end of file) with
the file reading. This is a way to check the state of the stream.
While using I/O streams, we have to include some header files. Whenever we use cin and
cout
, the file iostream.h, is included in which all these classes and objects have been
defined. For the formatted input and output, we manipulate the streams. To do stream
manipulations, we have to include a header file having the name iomanip.h. We can
understand that iomanip is a short hand for input output manipulation.
Page 452
Now let’s take a look at the standard streams which are provided to our programs.
Whenever we write a C++ program and include iostream.h in it, we get a stream for input
(reading) that is cin. This is a built in thing. We can use this object. Similarly, for output
(writing), we get cout. Other than these, we get some other streams by default. These
include cerr (read as c error) and clog. To understand these streams, we have to talk
about buffered input and output.

Buffered Input/Output


In computers, most of the components relate to electronics like chips, memory, micro
processor etc. There are also electro-mechanical things like disc. The key board itself is
an electro mechanical accessory. The electro mechanical parts of the computer are
normally very slow as compared to the electronic components. So there is a difference
between the two in terms of speed. Secondly, every input/output operation costs
computer time. Input/output costs and the I/O devices (keyboard, monitor and disc etc)
are slower as compared to the speed of the microprocessor and the memory being used.
To overcome this speed difference, we use the mechanism, called buffered input/output.
Suppose, we have a program which executes a loop. That loop outputs a number in each
of iteration to store in a file on the disc. If we write the output number to the disc in each
iteration, it will be the horrendously wastage of computer time. It means that the disc is
electro mechanical device. Similarly in each iteration, the mechanical movement takes
time. But if we gather the data and write it to the disc, there will be one mechanical
movement. The heads of the disc will move mechanically once to a point and the whole
chunk of data will be written on the disc. This is the more efficient way of using the disc.
So whenever we have a program that writes the output data to the disc, it will be nice to
collect the output data (numbers) and write it on the disc in one write operation instead of
writing the numbers one by one. The area where we gather the numbers is known as
buffer. The example stated in this case is the buffered output. In this case, the output does
not go directly to the disc. We first gather the data in a buffer and then write it on the
disc.
Now think about another situation. Suppose we have a program that performs very
complex calculations. It means that there is a while loop that performs so heavy
calculations that each of the iteration takes, say one minute and then provides the result.
Now we want to write that output to a file on the disc and see the iteration number of the
loop on the screen. We do not want to write the output to the disc after each iteration. We
gather the data in a buffer. In the meantime, we want to see the loop counter on the
screen. If we gather this output of counter number in a buffer, it may happen that the
buffer gathers the iteration numbers for 250 iterations before displaying it on the screen.
Thus, we see on the screen the numbers 1, 2, 3 …..250, when 250 iterations have been
performed. There are again 250 numbers gathered at one time. We see numbers 251, 252
……500, when 500 iterations have been performed. When we start the program, there
will be two buffers gathering data. One buffer gathers the data to write to the disc and the
other gets the data of iteration numbers to display on the screen. As we said that each
iteration takes one minute, meaning that the iteration numbers will not be seen for a long
time. Rather, these will be shown after 250 iterations (i.e. 250 minutes). During this
Page 453
period, we do not show any thing on the screen. Here, we are not sure whether the
program is executing properly as we do not see any iteration number on the screen. We
want to know after every minute that loop has executed once. So after every minute, the
loop counter should be displayed on the screen, so that at any time we could see how
many iterations have been performed. For this, we need unbufffered output on the screen.
Thus, in the same program we require buffered and unbuffered output.
Now these requirements are contradictory with different issues. These are met in our
system with the cerr object. cout is a buffered output. We cannot see it as nowadays
compilers are very intelligent. If you know UNIX, or command prompt and input output
redirection, we can actually see this in operation. Perhaps, you can create an example to
understand this. For the moment just try to understand that cout is buffered output. It
gathers data and sends it to the screen. On the other hand, cerr is unbuffered output. It
will show the data on the screen at the same time when it gets it. So cerr is an output
stream, an ostream object but unbuffered. It shows data immediately. So we can use
something like the cerr object that will show how many loops have been executed. It will
use something like cout to write on the disk to buffer the output. In this case, we are
getting efficiency in addition to information. Normally we use cerr object in C++ for this
purpose. Besides, we also have clog. It is also known as standard log having detailed
information of the log. To collect information of the program, we write it with clog.
Normally when we execute our programs- cout, cerr and clog, all are connected to
screen. We have ways to direct them at different destinations. That depends on the
operating system. Suppose, we specify the buffer size, normally the operating system or
compiler does this for us. A typical size of buffer is 512 bytes. When the information is
of 512 byte size, output will take place. But in the program, we may want at some point
that whatever is in the buffer, show them. Is there a way of doing that? The normal
mechanism is flush. Flush the stream. The flush command forces the data from the buffer
to go to its destination which is normally a screen or file and make the buffer empty.
Uptil now, we have been using two things to end the line. One is new line character i.e.
“\n”. When we are displaying something on the screen, it makes the next output to start
from the next line. The cursor moves to the left margin of the next line on the screen.
New line is just a character. The other one was endl. If we write cout << endl; It seems
that the same thing happens i.e. the cursor moves to the left margin of the new line. But
endl
actually does something else. It flushes the output too. As a result, it seems that cout
is unbuffered i.e. its output is immediately available on the screen. Depending on the
compiler and operating system, you may or may not see the buffered effect. But one thing
is clear that while reading the source code, you will know where cout is used and where
cerr
. Typically, that is also the programming style where the output of cerr is informative
and small. It shows that where is the control in the program. The output of cout is more
detailed and the actual output of the program. There are benefits of these things in the
code. In case of cin, it is alone. For output, we have cout, cerr and clog. In DOS, we have
two more output streams i.e. caux (auxiliary input output stream) and cprn (printer
output). These are no more relevant now.
Predefined Stream Objects:
Page 454

Object Meaning


cin Standard input
cout Standard output
cerr Standard error with unbuffered output.
clog Standard error with buffered output
caux Auxiliary (DOS only)
cprn Printer(DOS only)
Now let’s take a look at the operators associated with these streams. We have been using
the stream insertion operators ‘<<’ with cout. We need to understand that how these
operators are implemented. Using cout, we can chained the output. It means that we can
write as cout << “The value of the first integer is “ << i; This is the single cout
statement. How does that work? What happens is the first part goes to cout. In this case, it
is the string “The value of the first integer is”. The data travels in the direction of the
arrows. This string is inserted in the stream and displayed on the screen. What about the
rest of the statement i.e. << i; this again needs cout on the left side to be executed. It
should look like as cout << i; Once, we have defined that this is the behavior expected
by us. Then, we understand that this is exactly the way it has been programmed. The
stream insertion operator ‘<<’ is overloaded for the output stream and it returns the
reference of the output stream. The syntax of stream insertion operator is:
ostream& ostream::operator << (char *text);
The important thing to note is that this operator returns the reference to the ostream
object itself. Whenever we write a chained output statement, it is executed from left to
right. So cout << “ The value of the first integer is” is processed first from left to right.
The process is that this character string is displayed on the screen. As per the prototype
and definition, it returns the reference to the ostream object. In this case, the object was
cout
, so a reference to the cout object is returned. Now the rest of the statement becomes
as cout << i; It is processed quite nicely. This allows the stream insertions to be chained.
It is also applicable to the input. So if we say something like cin >> i >> j; both i and j
are integers. Now again, it is processed from left to right. This is the istream and the
extraction operator will return the reference to the istream object i.e. cin. So at first, the
cin >> i
is processed which will return the reference to the cin object. The rest of the
statement seems as cin << j; It is important to understand how these operators work. You
can see their prototypes that they return iostream objects themselves. That is the why, we
can chain them. Now let’s see what are the other various methods associated with these
input output streams.

Methods of streams


There are some other functions associated with cin stream. We have used some of them.
We have used get() and read() methods with input stream. Another member function of
cin
is getline(). It reads a complete buffer i.e. the number of character specified up to a
delimiter we specify. We can write something like:
cin.getline(char *buffer, int buff_size, char delimiter = ‘\n’)
Page 455
The character data is stored in *buffer. buff_size represents the number of characters to be
read. If we specify its value 100, then getline will read 99 characters from the keyboard
and insert a null character in the end. As you know, in C++ every character string ends
with a null character. We can also give it a delimiter. Sometimes, we may want to read
less character. Normally, the delimiter is the new line character. So while typing on the
keyboard, if we press the enter key then it should stop reading further and put the data
into the variable buffer. So there is a getline fiunction.
There are some other interesting functions also. When we use cin.get(), a character is
read. We can throw back the character gotten by this get function by using the unget()
function. So we can use cin.unget() that will return the most recently (last) gotten single
character.
We have a function peek(), also written as cin.peek(); The purpose of this function is that
we can see the next character that we are going to get. This function returns the next
character that would be read if we issue cin.get().
All these functions (getline, get, read, unget and peek) are implemented as member
functions of the input class.
Similarly, there are functions associated with cout. We have cout.putline(); which outputs
a buffer. Actually we have no need of this function because cout, itself, knows how to
handle character strings. Then we have cout.write(); which can perform a raw,
unformatted output. The function cout.put(); is like a formatted output. It performs
character by character output. We can do many formatting conversions by using the
stream insertion operator (i.e. <<) with cout. We can write an overloaded function of
stream insertion (<<) to input or output a complex number. We know that a complex
number has two parts i.e. real and imaginary. We can write the overloaded function such
that if we give two numbers with space between them it could read it. We can also write
it as that it could read two numbers (that are real and imaginary parts of a complex
number) separated by comma. Thus there may be different ways to write the overloaded
operator.
The white space character is very significant. We can show it by a simple example.
Suppose we have an array name of 60 characters. We get a name from the user in this
array by using cin and then display this string by cout. The code segment for this purpose
can be written as:
char name [60] ;
cin >> name ;
cout << name ;
Now when the user enters the name, suppose it enters ‘naveed malik’ that is a name
containing two words with a space between them. When we display this name by using
cout
, only ‘naveed’ is displayed on the screen. It means that only one word ‘naveed’ was
Page 456
stored in the array. The reason for it that the streams (cin, cout) are sensitive to white
space character that is treated as a delimiter. Now where is the second word ‘malik’. It
has not got deleted yet. It is in the buffer of the stream. This example will read like the
following:
char nam1 [30], name2 [30] ;
cin >> name1 >> name2 ;
Thus, we have two character arrays now. We can write ‘naveed malik’ and press enter.
The first part before space (naveed) will go to the first array name1 when that array is
used with cin. We will write another cin with name2 and the second part (malik) will go
to the second array name2. So things don’t disappear. They stay in the buffer till you
actually expect them. We have to be careful about that.

Examples using streams


A simple example showing the use of getline function.
// A simple example showing the use of getline function.
#include <iostream.h>
int main()
{
const int SIZE = 80;
char buffer[SIZE];
cout << " \n Enter a sentence: \n" ;
cin.getline(buffer, SIZE);
cout << " The sentence entered is: \n" << buffer << endl;
return 0;
}
Output of the program.
Enter a sentence:
this is a test
The sentence entered is:
this is a test
A simple example showing the use of read and write functions.
// A simple example showing the use of read and write functions.
#include <iostream.h>
int main()
{
const int SIZE = 80;
Page 457
char buffer[SIZE];
cout << " \n Enter a sentence: \n" ;
cin.read(buffer, 20);
cout << " The sentence entered was: \n";
cout.write(buffer, cin.gcount());
cout << endl;
return 0;
}
Output of the program.
Enter a sentence:
This is a sample program using read and write functions
The sentence entered was:
This is a sample pro

<Previous Lesson

Introduction to Programming

Next Lesson>

Home

Lesson Plan

Topics

Go to Top

Copyright © 2008-2013 zainbooks All Rights Reserved
Next Lesson
Previous Lesson
Lesson Plan
Topics
Home
Go to Top