SlideShare a Scribd company logo
1 of 26
Download to read offline
By: Asaye Chemeda Email: asayechemeda@yahoo.com 46
CHAPTER FOUR
INPUT AND OUTPUT IN C++
Introduction
Most C++ program applications involve three basic
stages: input, analysis and output. In the previous
chapters, all these stages were included in the programs
we wrote. We used several input as well as output
statements to read data into our program and to display
results on the screen. However, no emphasis was given
on the way how data input or output took place. This
chapter is devoted to analyze how input and output
processes take place in a C++ program and how the data
can be formatted and manipulated.
Input and output of data can take place from the default
devices. The default input device is the keyboard while the
default output device is the screen. Besides, the input and
output of data can also take place from other sources or
destinations such as files. In this chapter, input and output
procedures to both default devices and files will be
discussed. Whichever the source or destination is, the
input output in C++ is based on a concept known as
stream. Discussing about streams is vital for detailed
understanding of how input and output data can be
formatted and manipulated. Therefore, streams will be the
first topic in this chapter. Stay tuned till the end of the
chapter and you will love what we are going to discuss.
C++ Streams
What comes to your mind when you think of the word
‘streams’? A flow of water, right? Good imagination. Now
think of two places in which water flows from the first to
the second delivering goods in its direction of flow.
Streams in C++ are just like the flow of water between
the two points. They deliver data from input source to
your program or from your program to the destination.
In a water flow, it is the water which delivers goods. In
C++ streams, it is the sequence of bytes which delivers
the data. The sequence of bytes can be in a text or a binary
form. However, most C++ applications use the text form
of bytes which are characters. In short, streams are
interfaces through which sequence of characters is
transferred from a source to a destination.
A typical program reads data and displays the result. If so,
how many type of streams do we normally need to write
a program? Two, right? One of the streams conveys data
from an input source such as keyboard to the program.
The other stream conveys from your program to output
destination such as screen. Those streams through which
data is conveyed from input source to a program are
called input streams while the streams conveying data
from a program to a destination are called output
streams.
A stream may not only contain a single data at a certain
instance. A sequence of characters corresponding to a
number of data may be temporarily lined up in a stream.
In such cases, the data in the stream is said to be buffered
data.
You may raise an interesting question here. How do the
sequence of characters in the streams interact with a
program? Let me ask you a question before we answer
this. In almost all of the programs we wrote, we included
the <iostream> header file. Why do you think we did
that? It is because files like <iostream> have functions
which interact with streams. These functions interpret the
sequence of characters in the streams and convey it to the
appropriate variable in a program or the other way round.
Therefore, streams interact with programs through pre-
defined functions. The flow of data from a keyboard to a
program and from program to screen is pictorially
represented below.
The <iostream> file contains entities called classes
that contain functions which interact with the input
stream and output streams. The class which contains
functions which interact with input stream is called
istream. The class which contains functions which
interact with output stream is called ostream. In
addition, the <iostream> file contains a class called
ios. This class contains some of the variables and
operations for both input and output (I/O) operations.
To get access to the operations and functions in the
istream or ostream class, you need objects of the
classes. The objects are like blue prints of the class which
have the privilege to access the accessible members of the
class. For example cin is an object of istream and
cout is an object of ostream. The objects cin and
cout are built-in streams for input and output operations
respectively.
When a C++ program begins execution, four built-in
streams will be opened automatically. These streams are
By: Asaye Chemeda Email: asayechemeda@yahoo.com 47
cin, cout, cerr and clog. The cin and cout are
standard input and output streams respectively. Whereas
the cerr and clog are output streams for standard
error output and buffered error output respectively.
Some of the functions in istream or ostream classes
are invoked through the member access operator while
others are invoked with different operators. The member
access operator is a dot (.) while the other operators are
the extractors (>>) and inserters (<<).
The relevant functions in the <iostream> file will be
discussed next. Note that, whenever we want to use
operations and functions in istream , ostream or
ios classes, the file <iostream> should be included
in our program.
The inserter functions
The inserter functions are overloaded functions which
insert data obtained from the program into the output
stream through the insertion operator (<<). This
operator is a binary operator which takes two operands.
On the left side, it takes ostream class objects, i.e.
output streams, such as cout and on the right hand side
it takes variables of designated data type. The extractor
functions are overloaded so that any type of ostream
object and any data type can be used as operands. The
inserter functions are also overloaded to insert any
number of variables into a single output stream.
The general form of inserter functions is as follows:
The extractor functions
The extractor functions are overloaded functions which
extract data from the input stream and pass it to the
program through the extraction operator (>>). This
operator is a binary operator which takes two operands.
On the left side, it takes istream class objects, i.e. input
streams, such as cin and on the right hand side it takes
variables of designated data type. The extractor functions
are overloaded so that any type of istream object and
any data type can be used as operands. The general form
of extractor functions is as follows:
As shown in the above syntax, the extractor functions are
also overloaded to extract any number and data type of
variables with a single istream object.
Some of the rules to be followed for the extractor
operator are given below.
Rule 1: During extraction, any preceding white spaces
and new lines before any of the variables are
skipped.
Rule 2: Extraction takes place until a white space or an
input with a different data type than the data type
with which the variable is declared is
encountered.
Rule 3: When an extractor encounters a different data
type than the variable for which it is going to
extract value from the input stream without
extracting any value prior to the encounter, the
program will be in fail state and any further input
operations in the program will be aborted.
Rule 4: When an extractor encounters an input with a
different data type than the variable for which it
is going to extract value from the input stream
after some extraction was made, the extraction
will be terminated and the variable will be
assigned with extracted value before the
encounter. The rest data will be held in the input
stream waiting for the next input operation.
Rule 5: After completing the extraction, an extractor
function leaves a white space.
What did you feel when you read the above rules? Same
old same old? Or interesting? Anyways, we will see how
the above rules may resolve some tricky problems in
programs. Don’t you feel it is high time to write a program
to have a look at the implementation of the above rules?
Let us write one then. Note that, we are not going to write
a complicated program for this. It is the data which we
input which will make us realize how the above rules are
applied.
Program 4.1[Correct].cpp
By: Asaye Chemeda Email: asayechemeda@yahoo.com 48
The above program is simple, right? Two int variables x
and y, one double variable z, one character variable c
and one string variable s are declared. All the variables
except s were read with overloaded extraction operator
on line 11. Then the string variable is read on line 13. On
the subsequent lines, the entered values are printed. As we
said, it is not the program which matters. It is the data we
enter. Now, let us see what the output will be for different
input data.
First run,
Even if there were white spaces before the first input (10)
and the last input (12.76) on Input line 1, the
values of x and z are 10 and 12.76 respectively.
Because any preceding white spaces before the input data
were skipped (Rule 1).
Even if the string input on Input line 2 is “C++
is fun!”, only the string “C++” is assigned for s. This
is because, extraction took place only until a white space
was encountered. (Rule 2). Note that, the input stream
still contains the string “is fun!” which is a left over
from the extraction on line 13.
Second run,
While the first variable to be extracted is supposed to be
an integer, a character ‘B’ is the first input entered on
Input line 1. When the first extraction operation
encounters this and fails to extract the right value for the
int variable x, the program will be in fail state. All the
extractions after the encounter and any further input
operations were aborted. (Rule 3). No matter what values
were extracted after this, we will not get the results which
we expect. The displayed results also signify this.
Third run,
A continuous combination of characters were entered on
Input line 1. Since the first variable in the cin
statement on line 11 is an integer, the extraction
continued until a value with another data type, i.e.,
character H, is encountered. (Rule 4). The integer value
before the character, 13, is extracted and assigned to the
value of x and the rest values will be held for another
input operation. Note that, had there been no integer
before the character H, the program would be in fail state.
The next input operation is an extraction which attempts
to assign a character variable c. Since any entered
character corresponding to the ASCII list of characters
can be considered as a char data type, the first character
in the held values, i.e., H will be extracted as a value of c.
Since a char variable only takes one character, the set of
characters after H will be held in the input stream.
The next extraction will attempt to extract the left over in
the input stream and assign to the next variable which is
an integer. Since the next integer until a non-integer
character is encountered is 2091, this value will be
extracted as a value of y. Again, the rest values will be
held in the input stream and the extractor attempts to
extract them to a double variable. Since the dot character
is part of a floating point value and since the other held
values are numbers, all the remaining values will be
extracted to z. Note that, the dot character is not part of
an integer data type. If the extractor finds the dot
character for the first time and has to assign the values
after the dot to an int data type variable, the program will
become in fail state.
The white spaces preceding the string in the Input
line 2 were skipped and only the string before another
encounter of a white space, i.e., “Object-Oriented”
was assigned to the string variable s. The string after the
white space, “Programming” will be held in the input
stream.
The way how Rule 5 works is best elaborated with other
istream class functions and its discussion will be put
off until we discuss those functions.
What did you observe as strong sides of the insertion and
extraction operators? Definitely, it is their flexibility to
handle various forms of data. Do you agree? I hope you
do. The inserters and extractors are overloaded functions
and we have seen that they are very flexible in inserting or
extracting any of the basic data types in addition to string
variables. Besides, they can handle as many data as
possible for a single input or output stream.
Despite the above strong sides of them, however, we have
also noted some of the shortcomings of the extractors.
By: Asaye Chemeda Email: asayechemeda@yahoo.com 49
Could you guess the main drawback of the extractors? It
is the way they handle white spaces. They simply skip
them and ignore any data after white spaces. However,
white spaces may be part of the data and the data after
white spaces may be part of the data too. In such cases,
where white spaces or the data after them are important,
the istream and ostream classes have rich set of
functions. These functions will be discussed in the
subsequent topics.
The put and get functions
The put and get functions are members of the
ostream and istream classes. The put function is
used to convey a single character at a time to the output
stream whereas the get function extracts a single
character at a time from the input stream to a program.
Note that, the characters may also include white spaces,
tab and new line characters. Both functions are invoked
by applying the member access operator on the output or
input streams.
The general form of the put function is given below.
The above statement will send a char data type
characterVariable into the output stream. Note
that, the argument of put function can be a char data
type variable, a character literal or an integer
corresponding to the equivalent ASCII value for a
character. For instance, the following three cout
statements display the character A on the output device.
The statement on Line 2 inserts the value of the cVar
variable to the output stream. The statement on Line 3
delivers the character A to the output stream. The
statement on Line 4 delivers the character with ASCII
number of 65.
The get function has many forms. The frequently used
ones are the following:
The syntax given in Form 1 extracts a char variable
from the input stream and assigns the value to
characterVariable.
The get function given in Form 2 extracts a maximum
of number-1 characters from the input stream and
assigns the extracted characters to characterArray
which will be null-terminated by the function. The
extraction will also be terminated when a new line
character is encountered. The encountered new line will
not be removed from the input stream.
The get function given in Form 3 extracts a maximum
of number-1 characters from the input stream and
assigns the extracted characters to characterArray
which will be null-terminated by the function. The
extraction will also be terminated when a new line
character or a character the same as delimiter is
encountered. The encountered new line or delimiter
will not be removed from the input stream.
The get function given in Form 4 with empty
parameters extracts the next character in the input stream.
The return value of the function can be assigned to a
character variable.
When a program reaches statements like the above get forms, it
extracts one or more characters from the input stream, if there is any,
until the condition for terminating the extraction is filfilled.
Otherwise, the program waits until a user enters a value.
The following two statements assign the character
variable cVar with the next character in the cin stream.
Even if the above get form and put functions only
hand one character at a time, suitable loops can be used
to navigate through a large number of characters.
The following statement extracts characters until new line
character is encountered or a maximum of 99 characters
are extracted and assigns the characters to cArray. By
the process, cArray will be null-terminated.
The following statement extracts characters until new line
character is encountered or a dot is encountered or a
maximum of 19 characters are extracted and assigns the
characters to cArray. By the process, cArray will be
null-terminated.
Let us see the implementation of these functions in a
program.
By: Asaye Chemeda Email: asayechemeda@yahoo.com 50
Program 4.2[Correct].cpp
In the above program, a character variable c and a string
variable str were defined on lines 6 and 7. The string
variable is read with an extraction operator on line 9. If
the data which we entered for str contains internal white
spaces, any characters after the first internal white space
will be held in the input stream. (Rule 2 of extraction
operator). The next input operation will then start
extracting the left overs. Since the next input operation is
the cin statement on line 14, the held characters will be
extracted by the get function one by one until a new line
character is encountered. The continuation of the
extraction until new line character encounter is because
the criteria for the termination of the do-while loop is so.
Now, let us enter “C++ is fun!” as an input. The set
of characters until the first white space, i.e., “C++” will be
assigned to str variable. Each of the rest characters, i.e.,
“ is fun!” will be extracted by the cin.get(c)
statement and printed by the cin.put(c) in the do-
while loop. The output when the above string is entered
looks like:
By the way, what do you think will happen if we enter a
string with no spaces? All the characters in the string will
be assigned to the str variable, right? The interesting
question is: what will be read by the cin statement on
line 14 if all the characters are assigned to str? Will the
program wait until we enter a value? If you answer this
correctly, it means that you have remembered Rule 5 of
the extractor function. Even if a string with no white
space is entered, the extraction operator leaves a white
space after it extracts. That white space will be extracted
by the cin.get(c) statement on line 14 and the
program will not wait for us to enter a character.
Reading and writing any characters including white
spaces, tab and newline characters were the strong sides
of put and get functions. Did you notice that they have
major drawbacks too? It is obvious, the main drawbacks
of the put and get functions are the fact that they can
only handle one character at a time and that they only
interact with character variables. The first drawback can
be solved if there are functions which read or write a
number of characters at a time. Such functions are
discussed next.
The getline,read and write functions
These functions are members of the istream and
ostream class which read or write one or more
characters in a single line. The getline function is
invoked by input streams while the write function is
invoked by output streams with a member access
operator.
The getline function extracts characters from the
input stream and assigns them to a character array variable
or a string variable. When the extracted characters are
assigned to a character array variable, the null character is
automatically appended to the character array. The
getline function may have one of the following three
forms:
The statement in Form 1 is used to extract characters
from istreamObject and assign the characters to the
characterArray. The rules for the extraction are:
Rule 1: The extraction continues until number-1
characters are read or new line character is
encountered whichever comes first.
Rule 2: If a new line character is encountered before
reading number-1 characters, the extracted
characters will be assigned to the
characterArray.
Rule 3: If there are more than number-1 characters in
the input stream and the newline character is not
yet encountered, the program will become in fail
state.
Rule 4: Null character is automatically appended at the
end of the characters.
The statement in Form 2 is used to extract characters
from istreamObject and assign the characters to the
characterArray. The rules for the extraction are:
By: Asaye Chemeda Email: asayechemeda@yahoo.com 51
Rule 1: The extraction continues until number-1
characters are read or a character the same as
delimiter is encountered or new line
character is encountered whichever comes first.
Rule 2: If a new line character is not encountered before
reading number-1 characters, and if a character
the same as delimiter is encountered, the
extracted characters before the delimiter
will be assigned to the characterArray.
The delimiter is extracted from the input stream
but it will not be included in the characters
assigned to the characterArray.
Rule 3: If a new line character is encountered before
reading number-1 characters, and a character
the same as delimiter is not yet encountered,
the program will become in fail state.
Rule 4: If there are more than number-1 characters in
the input stream and the newline character or the
delimiter is not yet encountered, the
program will become in fail state.
Rule 5: Null character is automatically appended at the
end. However, if a character the same as the
delimiter is encountered, a white space but not a
null character is appended.
The statement in Form 3 is used to extract characters
from istreamObject and assign the characters to the
stringVariable. The extraction continues until new
line character is encountered.
The read function extracts characters arrays from an
invoking input stream. The general form of the read
function is:
In the above statement, the read function extracts
length number of characters from
istreamObject and assigns to characterArray.
The extraction continues until length number of
characters are extracted.
The write function inserts characters arrays to an
invoking output stream. The general form of the write
function is:
In the above statement, the write function inserts
length number of characters from
characterArray into ostreamObject. The
insertion continues until length number of characters
are inserted even if a null character is encountered. A
number of write functions can be concatenated on a
single output stream. The concatenated form of the
write function is given for the cout output stream as
follows:
We haven’t yet looked into any specific statements for
C++ programs using the getline and write
functions. Once we know how they are invoked and what
arguments they take, it is not that difficult to write few
statements though. The following program shows the
implementation of the functions in a program. Recalling
about how dynamic arrays are created might be necessary
for complete understanding of the program.
Program 4.3[getline skipped].cpp
In the above program, an int variable len, a character
array c and a string pointer p were declared on lines 6, 7
and 8 respectively. The variable len will be used to store
the size of a dynamic string array which is going to be
created. The pointer p will be used to create the one-
dimensional dynamic string array with a size of len. On
line 9, the user is prompted to enter the length of the
string array, i.e. the value of len. This value is read with
the extraction operator from the cin stream on line 10.
Due to the statement on line 11, a dynamic memory for
len number of string variables will be allocated at run-
time and the base address will be passed to the pointer p.
The user is prompted to enter len number of strings on
line 12. The for-loop from line 13 through line 15 extracts
a line of string from the cin stream and assigns to each
row of the dynamic array. The for-loop between line 17
and 19 will display these strings using the insertion
operator.
By: Asaye Chemeda Email: asayechemeda@yahoo.com 52
On line 20, the user is again prompted to enter a character
array. By the statement on line 21, a maximum of 9
characters will be extracted from the cin stream by the
first form of the getline function and will be stored
into the character array c. Two concatenated write
functions on line 22 will insert 7 characters from the string
“Output:” and 9 characters from the c into the cout
stream.
On line 23, the user is prompted to enter a character array
with a comma. The comma will be used as a
delimiter. On line 24, the second form of the
getline is invoked by cin to extract a maximum of 9
characters from the invoking stream and assign it to c. if
the line of characters contain a comma within the first 9
characters, the extraction will be terminated. Another
concatenated write function similar to the one on line
22 is used to insert the new value of c to cout stream so
that it will be displayed on the screen.
Now, let us run the program and enter the required data
and analyze the output. Here is an output from a sample
run.
In the above sample run, the length of the string or the
value of len is entered to be 3. After this, the program
prompted us to enter 3 strings. Let us enter “Input
stream” as the first string, “Output stream” as the
second string. But when we were ready to enter the third
string, the program did not let us. It just printed the two
strings which were entered. The value of len is 3 and we
expected the program to wait for us until we enter 3
strings; each followed by pressing the ‘Enter’ key which
creates a new line character. But, why did the program not
let us to enter the third string? Is there anything wrong
with the for-loop? Did we make it loop only two times?
No. It loops three times. Did we introduce a newline
character in the middle of the strings we entered and the
getline function picked two strings within a single
loop? No. We introduced the new line character only at
the end of the strings we entered. What is going on then?
Recalling Rule 5 of the extractor function will solve the
mystery. The rule says the extractor operator (>>) leaves
a white space after extracting in the input stream. Now,
let us look at line 10 of the program. The extractor
operation is used to extract the value of len from the
cin stream. Which means that according to the rule,
there white space is still there in the cin stream after the
statement on line 10.
During the first loop of the for-loop between lines 13 and
15, the getline function on line 14 gets this white
space in the cin stream and the newline character after
that. As a result, the getline function will not make
the program wait for us to enter a character during the
first loop. It already assigned the white space in the cin
stream as the first row of the dynamic array. What
happened after this? Only two loops were remaining and
the program waited for us to enter only two strings for
the second and third rows of the dynamic array. Now,
look at the output. There is a white space between the
phrase “The printed strings are:” generated
by line 16 of the program and the print of the first string
we entered. This white space is the first row of the
dynamic array.
After this, the program prompted us to enter a character
array to be extracted by another form of getline
function on line 21. Since the maximum number of
characters which this getline function call extracts is
9 (=10-1), we entered the string “Iostream” which
has 8 characters. Note that entering more than 9
characters would have resulted in the program to be in fail
state. This string was inserted into the cout stream by
the write function on line 22 and exactly what we
entered was printed.
By the statement on line 23, we were prompted to enter a
character array with a comma. We entered the string
“ios,istream,ostream”. This string was
extracted by the getline function on line 24. This
getline function extracts a maximum of only 9
characters or until it encounters comma. In the string we
entered, comma appeared as a fourth character.
Therefore, it extracts only the first three characters, i.e.,
“ios” and it assigns them to the character array c. By
Rule 5 of getline function, when a delimiter is
encountered before extracting all the characters, a white
space without a null character is appended to the
extracted string. Note that, the character array c was
already assigned with 8 characters and a null character was
appended by the statement on line 21 and by the
“Iostream” string we entered. After the getline
function on line 24, however, the first three characters in
By: Asaye Chemeda Email: asayechemeda@yahoo.com 53
c were replaced by the characters ‘i’, ’o’ and ‘s’
respectively and the fourth character was replaced by a
white space appended to these characters. Which means
that the first four characters extracted by the getline
function on line 21 were replaced with the four characters
extracted by the getline function on line 24. Since null
character is not appended to the characters extracted by
the getline function on line 24, the unreplaced
characters in c still exist. Therefore, when c is printed by
the write function on line 25, the displayed string is
“ios ream”.
By the way, we have solved the mystery why the
getline function in the for-loop between lines 13 and
15 is not waiting for the same number as the value of len
we enter. Can you give any suggestion how this could be
improved? One of the ways to make the getline
function inside the for-loop wait for the same number as
the value of len is to extract the white space left in the
input stream before the for-loop is entered. One of the
ways to do this is to use the get function. For instance,
including the following statement anywhere between the
cin statement on line 10, where the white space is
produced, and the first for-loop will solve the problem.
Recall that we used the same approach in Program 3.8 in
chapter three. On line 10 of program 3.8, we introduced
the above statement to extract a white space left from an
extraction operator.
There are also other ways by which unwanted characters
such as the white space produced by the extraction
operator in Program 4.3, can be excluded from a string.
The above option by using the get function only removes
only one unwanted character at a time. In addition, it is
not an ultimate way of removing unwanted characters
from a string. C++ provides with another function by
which any number of unwanted characters can be
removed from an input stream. This function is the next
topic to be discussed.
The ignore function
Another member of the istream class, ignore,
discards specified number of characters or the characters
before a delimiting character is encountered from the
invoking stream. The function is overloaded to have the
following two formal parameter types.
In the syntax given by Form 1, the ignore function
discards number characters from the
istreamObject. The ignore function syntax given
by Form 2 discards a maximum of number characters
from the istreamObject if delimiter is not
encountered. If a delimiter is encountered before
discarding number characters, the discarding will be
terminated after the delimiter is removed from the
input stream.
The default value for number is 1 and we can omit
passing the value of number as an argument; in which
case, the function assumes its value to be equal to 1.
Let us consider the following piece of code.
In the above piece of code, a character array c with a size
of 100 is declared on Line 1. The statement on Line 2
makes the program wait until the user enters a character
and discards 5 of them. If fewer than 5 characters are
entered, the program still waits for an input. The
ignore function also discards the newline character
which is produced by pressing the ‘Enter’ key. After
discarding 5 characters the program will proceed to
executing the next line.
The statement on Line 3 discards a maximum 10
characters or all the characters before the delimiter ‘,’ is
encountered, whichever comes first, from the cin
stream. If the delimiting character is not encountered nor
10 characters are not yet removed, the program waits for
other characters to be entered.
After 5 characters are discarded by the statement on Line
2 and 10 or the characters before ‘,’ are removed by the
ignore function on Line 3, what is left in the cin
stream will be extracted by the getline function on
Line 4. If there is no any character in cin by then, the
program will wait for other characters to be entered.
By the way, the ignore function is the best candidate to
solve the problem which we faced in Program 4.3, by
discarding the unnecessary white space produced by the
extraction operator. Since the default value for number of
characters to be discarded is one, the following statement
could also be used to discard the unnecessary white space.
So far, we have learned a number of functions which are
used to interact with the input and output streams. Didn’t
By: Asaye Chemeda Email: asayechemeda@yahoo.com 54
they widen the options which we have to control what is
passed to the program from the input stream and what is
delivered to the output stream? Definitely yes. The
functions which we learned are not the only ones and
there are plenty. Are you interested in learning few more?
I hope you are. Let us discuss the next ones then.
Have you noticed that all the functions which we
discussed so far always removed the characters which they
handled from the input stream? What if we want to
operate on a character without removing it from the input
stream? What if we want to put back characters into the
input stream? Does C++ answers for this question too?
Of course, it does. The next topic will show us how.
The putback and peek functions
These functions are members of the istream class.
Both functions can only handle one character at a time.
The putback function puts back a character literal or
the value of any character variable into the invoking input
stream. Whereas the peek function returns the value of
the first character in the invoking stream without
removing the character from the stream.
The syntax for the putback function is:
The above statement puts characterVariable
back into the istreamObject.
The syntax for the peek function is:
The above statement returns the value of the first
character in the istreamObject and assigns its value
to characterVariable.
Let us consider the following code fragment.
On Line 1, a character variable c1 is declared and
initialized with what is going to be read by the
cin.get(). The cin.get() on Line 1 makes the
program wait for a character to be entered. When a
character is entered, the get function on Line 1 removes
it from the cin stream and assigns it to c1. This
character, which is assigned to c1, is put back into the
cin stream by the putback function invoked by cin
as it is done on Line 2. After Line 2, the first character in
the cin stream will be the character stored in c1.
The peek statement on Line 3 reads the first character
within the cin stream, which is the same as c1, and
returns the value for a new character variable, c2. Note
that the peek function doesn’t remove the character
from cin. It just returns its value.
The cin.get() on Line 4 then extracts the first
character from cin and assigns it to a new character c3.
The statement on Line 4 doesn’t make the program wait
for a character to be entered. Because there is already a
character in the input function. The character which is
extracted from cin by the get function on Line 4 is the
same character which was put back by the statement on
Line 2 and which was copied by the peek function on
line 3. Therefore, after Line 4, the value of the characters
c1, c2 and c3 will be the same as the value which was
entered on Line 1.
Some of the functions which interact with the input
stream may result in a program in fail state if inappropriate
data is entered. For instance, if the extraction operator
encounters a different data type than what it expects and
if it can’t have other options to bypass the inappropriate
data, the program will become in fail state. The
getline function can also lead to a program in fail state
if more characters than what it expects is introduced into
the input stream. Do you remember what the
consequences of a program in fail state are? All further
input operations will be aborted and the output
operations will display flawed results.
In real world programs, however, entering inappropriate
data may normally occur. For instance, in a software
developed by C++ program, a user may enter
inappropriate data. In such cases, the program would
become in fail state. However, this is not how a good user
interactive software is developed. The program should be
capable to reverse any wrong data input into a normal
working state. You may raise this question at this point: is
it possible to resume a normal input operation after the
program became in fail state? Of course it is. The next
topic will show us how.
The clear function
Among the members of the istream class, the clear
function, restores a program which is in fail state into a
working state. However, to maintain a normal input and
output process, the unnecessary data in the input stream
should be cleared first after the clear function is
invoked. This may be done using the ignore function.
The syntax for using the clear function is:
By: Asaye Chemeda Email: asayechemeda@yahoo.com 55
The clear function is best used with logical statements
where a program continues with execution if appropriate
data is entered or the program is cleared with clear
function and the program is ready for another execution
with another set of data.
We have now covered what we need to discuss regarding
the built-in functions which interact with the input and
output streams. But, we haven’t seen a full program in
which the latest functions which we discussed: ignore,
putback, peek and clear were used. The program
below uses all of these functions. Some of the procedures
in the program are just introduced to show how the above
function can be implemented in a program. There could
also be other straight forward approaches. Anyways, let
us have a look at it and discuss the basic points.
Program 4.4[Correct].cpp
The above program will be used to prompt a user enter
five names along with their scores, store these user inputs
and display the names and the corresponding scores. In
the program, a character variable c, a boolean variable
isFailState, a float array score and a two-
dimensional character array name were declared from
line 4 up to line 7 of the program. The variable
isFailState is initialized with false and the
number of rows of score and name are defined to be
5.
Two for-loops are used in the program. One to for the
input part another for displaying the names and scores.
The first for-loop extends from line 8 up to line 30
whereas the second for-loop is between lines 32 and 38.
The body of the first for-loop starts by prompting the
user to enter a name. Then, there is a do-while loop
between lines 10 and 12. This loop is intended to discard
any white spaces before the entered name. It could also
be done within a single line by using the ignore
function. The reason why the loop is introduced is to
show how the putback function is used.
In this do-while loop between lines 10 and 12, a character
is extracted from cin and assigned to the variable c by
using get function. The loop continues while the
character stored in c is equal to the white space character.
As soon as the variable c gets non-white space character,
i.e., after all the white spaces are discarded, the loop will
be exited. However, the last loop extracts and assigns the
first non-white space character to c. This character is part
of the name entered by the user. Therefore, it should be
put back into the input stream. The statement on line 13
performs this task using the putback function. Then,
the rest characters will be extracted by the getline
function on line 14 and will be assigned to the ith row of
name array, i.e., name[i].
On line 15, the user is prompted to enter the score for the
entered name. Note that, if the user enters a data which
doesn’t correspond to float data type, the program will
become in fail state. If so, any further input operations
will be aborted. Don’t you think this makes the user
irritated? Suppose you are using a software and you
entered a wrong data by mistake and the program stops
working as a result of that. Don’t you get frustrated by the
software? You might be. Therefore, if you are a
programmer writing a code for a software and if you want
your software to be competitive, you should foresee such
issues. Then, what could be done in this particular
program to avoid a program in fail state? We can use the
clear function, right? But how do we know whether a
wrong data was entered or not? We should check whether
the data is entered correctly or not while the data is inside
the input stream. Are there facilities in C++ to achieve
this goal? Of course there are. We can use the peek
function, right? That is what the if-statement on lines 16
and 17 will do. It checks what kind of data is in the cin
stream without removing the data. Note that the return
value of the peek function is the ASCII value of the
character.
By: Asaye Chemeda Email: asayechemeda@yahoo.com 56
If the first character in the input stream is a floating point
number, its value should be between 1 and 9 (excluding
scores which are less than 1). The peek function will
now be used to check whether the character in the cin
stream is a whole number between 1 and 9. The ASCII
numbers of the characters 1 up to 9 is 49 up to 57 in their
respective order. Therefore, after the user entered a value
corresponding to score and if the first character in the
input stream is a character with ASCII value outside the
above range, it will lead to a program in fail state. In these
cases, we need a flag within the program to indicate that
the program is going to be in fail state. Like the flag in
football games which will be raised when a ball crosses
the boundary lines. In program 4.4, the flag is the
isFailState boolean variable. After the user is
prompted to enter the score and if the ASCII value of the
first character entered by the user is less than or equal to
48 or greater than 57, the value of isFailState
becomes true, otherwise its value will remain to be
false. In short, the if-statement on line 16 changes the
value of isFailState to true when the first
character in the cin stream is not a number between 1
and 9.
On line 18, the extraction operator is used to extract the
input for the ith row of score. Note that, if wrong data is
entered, this statement will lead the program to be in fail
state. If so, however, the if-statement on line 16 would
have already foreseen this and would have changed the
value of the isFailState variable to true. If the
value of isFailState is true, another if-statement
extending from line 19 to line 28 executes the clearing and
brings the program into a working condition.
When the statement on line 18 makes the program to be
in fail state, the statements within the body of the second
if-statement will be executed. In this if-statement, the
program will be restored into a working condition by the
statement on line 20 using the clear function. Then the
ignore function used on line 21 discards the
unnecessary characters in the cin stream. After this, the
user is prompted to enter a correct score. Note that, at
this time too, the user may enter inappropriate data.
Therefore, a while loop is used to loop until the user
enters a correct value for a float data type variable. The
truth statement for the while loop is the same as that of
the if-statement on line 16. Within the while loop, the
unnecessary characters in the cin stream will be
discarded each time the user enters a wrong data. Actually,
this could also have been done on line 16 itself instead of
the if-statement and we could have avoided a few
statements within the program. However, if statement is
used on line 16 to show how the clear function works.
The cin statement on line 27, extracts a value for the ith
row of score array once the program entered into a fail
state. The statement on line 29, discards one unwanted
character. Can you guess what that unwanted character
could be? It is the white space produced by the extraction
operator on line 18 or the one on line 29. On line 30, the
value of isFailState is assigned with a value of
false. Otherwise, the program enters the if-statement
on line 19 on the next loop even if the user enters correct
data.
The content of the second for-loop between lines 32 and
38 is straight forward. The statement to note may be the
while loop on line 34. This while loop is used to count the
number of characters in each row of the name array
before the null character. The number of characters is
determined by incrementing the value of an int variable j
until the null character is encountered. When the while
loop is exited, the value of j will contain the number of
characters for the ith
row of the name array. Then this is
used to insert the exact number of characters into the
cout stream by using the write function. A cout
statement is used on line 36 to display the corresponding
score for each name.
The above program may require further enhancements to
avoid all possible runtime problems. However, we have
used it satisfactorily in order to see how some of the built-
in functions in the istream and ostream classes are
used in a program.
Let us now have a closer look at how the output stream
works. When data is fed to the output stream, it will not
send all the data to the output device immediately. It
keeps on storing the data in a buffer until the stream is
full. Sending the data to the output device only starts after
the stream is full. Now, consider there is a power outage
after a data is inserted by a program to the output stream
and before the output stream becomes full. What do you
think will happen? The output device will not display the
data which the program is supposed to do. Because the
data was still in the output stream waiting for the output
stream to be full and to start being displayed on the output
device. But, is there any way in C++ by which we can
force data in an output stream to be flushed to the output
device? Of course there is. The next topic will discuss how
this is done.
The flush function
The member of ostream class, flush, forces any data
within the output stream to be sent to the output device
without waiting for the stream to be full. The syntax to
use the flush function is:
By: Asaye Chemeda Email: asayechemeda@yahoo.com 57
If the flush function is invoked as in the above
statement, any data within ostreamObject will be
flushed to the output device automatically.
The concepts which we discussed so far deal basically
with how the input and output streams work and how
different functions interact with these streams. The
majority of the built-in functions which we discussed
mainly deal with extraction or insertion of data from or to
streams. None of them were used to deal with arranging
the data in a formatted manner. However, some real
world programming applications may require the outputs
to be displayed in specific formats. For instance, a
programming application which calculates the total price
of goods may need to be programmed to send a value in
exactly two decimal places to the printing device.
Some of the functions which we discussed previous may
be combined to have such formatted output. But, those
approaches would require more lines of coding. In
programming, achieving the desired programming goal
with the fewest number of statements is usually
preferable. Because, the more the number of statements,
the more vulnerable the program will become for errors.
In addition, fewer lines of coding make a program to be
neater. As a result, instead of using the functions in the
istream and ostream classes to have a formatted
input or output data, the other set of built-in C++
functions can be used. The outputs through put and
write functions are unformatted outputs and cannot be
made to have a specific formatting style.
Formatting of outputs in C++ is usually done by using
the built-in functions in the iostream file or in the
iomanip file. The ios class in the iostream file has
a number of functions which are used to arrange an
output in a desired way. A similar formatting can also be
done by the so called manipulator functions in the
iomanip file. However, the formatting functions in
both files have their own limitations and capabilities.
Based on these limitations and capabilities, the functions
which can achieve a desired formatting style for an output
from either of the files can be selected at the
programmer’s discretion.
Formatting output using the ios class functions
The ios class in the iostream file has a number of
functions which can be used to have a specific format for
an output. Some of the functions in this class are listed
below.
width – allocates a specified number of
character spaces for an output.
precision – puts the output in specified
number of decimal places.
fill – fills empty spaces of the allocated
character spaces for an output with designated
character.
setf – sets a specific flag for an output.
unsetf – reverses the flag set by setf
function.
flags – returns the current formatting style or
sets formatting style contained by a variable.
All of the above functions are invoked by an output
stream (ostream class object) by using the member
access operator. Now, let us see how the above functions
can be used in a program.
The width function
The syntax used for width function is:
The above statement allocates number character spaces
for the very next output operation to the
ostreamObject stream. If the number of output
characters to be displayed is greater than number, all the
output characters will be displayed outside the boundary
allocated by the width function. Let us consider the
following piece of code:
In the above piece of code two float variables x and y are
declared on Line 1. The variable x is initialized with a
number which has two digits before the decimal place and
three digits (including the trailing zero) after the decimal
place. Whereas the variable y is initialized with a number
which has one digit before the decimal place and two
digits after the decimal place. Note that the variable x has
six characters including the decimal point and the variable
y has four characters.
On Line 2, ten character spaces are allocated for the next
output operation using the width function. Therefore,
the very next output operation will be accommodated on
the right side of these 10 character spaces. The output will
be accommodated on the right side because by default an
output is displayed right-justified.
On Line 3, the values of x and y are inserted into the
cout stream using the insertion operators. Since the first
output operation after the formatting on Line 2 is the
insertion of the value of the variable x into cout stream,
the value characters in the value of variable x will be
accommodated on the right side of the 10 character
spaces allocated by the width function on Line 2. Note
that the value of the variable x has six characters including
By: Asaye Chemeda Email: asayechemeda@yahoo.com 58
the trailing zero. However, trailing zeroes are not
displayed in the output unless the format setting is
changed to do so. Therefore, only five of the six
characters (including the decimal point) without the
trailing zero will be accommodated within the 10
character spaces. Therefore, the displayed output by the
statement on Line 3 appears to be:
In the above output, it can be observed that the value of
the variable y is displayed next to that of x without being
formatted. However, the trailing zero in the variable x is
omitted in the displayed output. Since x has five
characters to be displayed and ten character spaces were
allocated for it, there are five unoccupied character spaces.
To understand a little bit more about how the width
function operates, let us consider the following piece of
code.
The output of the above piece of code will look like:
Even if the width is set to 3 on Line 2 for displaying value
of x which has five displayable characters, all the five
characters were displayed. Therefore, if the number of
displayable characters in an output is greater than the
width set by the width function, the later will be
overruled.
On Line 4, another setting for width of an output is set.
In this case, 10 character spaces were allocated for the
next insertion operation which is displaying the value of
square root of 3. Note that square root of 3 is an irrational
number and it has infinite number of digits. But, the
number of displayed digits after decimal places for most
compilers is six. Therefore, six digits will be displayed
after the decimal place if there are no trailing zeroes and
if the setting for default number of decimal places is not
changed. The value of square root of 3 up to six decimal
places is 1.732051. Which means that there will be 8
displayable characters. However, 10 characters spaces are
allocated. Which means that there will be two unoccupied
spaces. Note that when the width function allocates
character spaces, the counting for the allocated spaces
starts from the very last character in the output stream
unless a newline character is introduced.
When character spaces are allocated for an output using
the width function, the number of digits after decimal
places are fixed unless the setting is changed to display
more number of digits. But, some numbers, such as the
value of π, may contain more than the default value of
number of digits and it may be required to display all the
digits.
In those cases, another function of the ios class can be
used. This function will be the next topic to be discussed.
The precision function
The syntax used for precision function is:
The above statement sets number digits to be displayed
after the decimal place when an output is displayed from
ostreamObject until the setting is changed. The
function can also be called without passing an argument.
In that case, it returns the current precision setting of the
program. The precision function will not force
trailing zeroes to be displayed.
The use of the precision function is shown in the
following piece of code.
The statement on Line 1 prints the current precision
setting by using the precision function with empty
parameters. If the precision has not been set before, this
statement will display a value of six for most compilers.
The statement on Line 2 indirectly prints the value of π
which is also equal to two times sine inverse of 1 in radian
units. This line prints the output as below and there are
six digits after the decimal point.
On Line 3, the precision setting is changed to ten digits
after the decimal point. The statement on Line 4 displays
the precision setting after it was changed on Line 3. This
will display a value of 10. The statement on Line 5 again
prints the value of π after the setting is changed. The
displayed output will be:
Now, the printed number of digits after the decimal point
has become 10 as it was set by the statement on Line 3.
By: Asaye Chemeda Email: asayechemeda@yahoo.com 59
Based on our discussion, can you answer what will be
displayed by the statement on Line 3 of the following
piece of code?
Did you answer as 39.700? Or did you recall that the
precision function will not force trailing zeroes to be
displayed even if the precision setting includes them? The
cout statement on Line 3 prints only 39.7 omitting the
trailing zeroes. The width function allocates six
character spaces put the four displayable characters on the
right hand side as follows.
When the number of characters in an output are less than
the space allocated by width function, there will be
empty character spaces in the displayed output. However,
some programming applications may require to avoid
such unoccupied character spaces when the output is
printed. For instance, unoccupied character spaces in
bank checks may need to be avoided to prevent any
addition of extra digits in the unoccupied character
spaces. As a result, the empty character spaces may need
to be avoided. At the same time, a program application
may need to set the width with small as well as large
number of characters so that outputs with wide range of
characters will be accommodated. Then, when outputs
with small number of characters are printed, there will be
unoccupied characters spaces. In such cases, we can use
another function from the ios class. This function will
be discussed next.
The fill function
The syntax used for fill function is:
The above statement fills unoccupied character spaces
with character for the coming output operations to
the ostreamObject stream. The value character
can be a character literal or a character variable. The
format setting by fill function persists until the setting
is changed. To see how the fill function operates, the
following code fragment will be considered.
In the first line of the above code, the double variable
amount is declared and initialized with a number having
five characters (including the decimal point). On Line 2,
the width for the next insertion operation is set to 10.
The statement on Line 3 fills any unoccupied spaces with
the ‘*’ character by using the fill function. The value
of amount is inserted to cout stream as the first
insertion operation on Line 3. Since amount has only
five characters and since 10 character spaces are allocated,
it is expected that five of the spaces will be filled with the
‘*’ character. The value of amount will be displayed as
follows:
The unoccupied five spaces are now filled with the
character which is used as an argument when the fill
function is invoked. Note that the filling by fill
function takes place wherever there is an empty space;
whether it is in front of or inside or after the displayed
output value.
By the way, we do not have to take output formatting as
a luxury topic. Some programming applications may
require strict output styles. Therefore, detailed
understanding about the formatting facilities in C++
might be vital. We have already discussed how some
formatting styles can be achieved. Besides, we have also
noted some formatting styles which couldn’t be handled
by the functions which we discussed so far. For instance,
none of the formatting functions which we discussed
couldn’t enforce the displaying of trailing zeroes. The
functions couldn’t also change the justification of the
output. However, this doesn’t mean that C++ doesn’t
have the facilities to handle those styles at all. Other styles
which were not achieved by the previous ios class
functions can be easily handle by setting different flags.
In C++, flags are Boolean variables which signify that a
certain state is reached within the program. For instance,
a state may be reached when right-justified output setting
is just to be changed to left-justified output setting. In
such cases, we need flags to indicate that a particular state
is being reached. There are a number of flags for different
programming states. These flags can be set and unset
thereby achieving some desired output style. How this is
done will be the next topic to be discussed.
The setf , unsetf and flag functions
The setf function is an overloaded function and may
have one of the following two forms:
The syntax given in Form 1 takes one argument. By this
statement flag is set for the outputs through
ostreamObject and the flag will persist until it is
By: Asaye Chemeda Email: asayechemeda@yahoo.com 60
unset. As part of the argument the function name where
the flag belongs (ios) and the scope resolution operator
(::) should always precede the flag.
The syntax given in Form 2 takes two arguments. By
this statement previous settings corresponding to flag2
will be cleared first and flag1 will be set as a flag for the
coming output operations into ostreamObject and
the flag given by flag1 will persist until it is unset. Both
arguments should be preceded by the function name
where the flag belongs (ios) and the scope resolution
operator (::).
A number of flags can also be combined as a single setf
function argument using the OR operator. This avoids
writing multiple lines which could be written to change
the setting for each flag. The syntax for such setf
function with combined flags when invoked by the cout
stream is given below.
The frequently used flags in ios class are:
left – makes the output left-justified.
right – makes the output right-justified.
showpoint – enforces displaying of trailing zeroes.
showpos – displays the + sign when positive numbers
are displayed.
fixed – puts the output in fixed number notation.
scientific – puts a floating-point output in scientific
notation.
boolalpha – allows input and output of Boolean
values by using the keywords true and false.
dec – displays an output as decimal (base 10) number.
oct – displays an integer output as octal (base 12)
number.
hex – displays an integer output as hexadecimal (base 16)
number.
The following flag groups consist of more than one flag
and can only be used as a second argument in the setf
function which takes two arguments.
adjustfield – refers to the left and right flags.
floatfield – refers to the fixed and
scientific flags.
basefield – refers to the dec, oct and hex flags.
The frequently used flags which can be set to display an
output in different styles are given above along with
explanations what the specific effect of each flag is.
Instead of looking into pieces of codes to discuss how
each of the flags affect an output setting, let us write a
program and analyze the displayed outputs. For this, let
us consider the following program first and the resulting
output.
Program 4.5[Correct].cpp
The output for the above program is shown below. Since
the only formatting functions used in the above program
are width and fill and since the effect of these
functions was discussed in detail, no further discussion
will be made on the output.
Now, let us introduce the left, showpoint and
showpos flags in the program and analyze the output. A
Boolean variable isPrintComplete was also
declared and initialized with a value of false. This
variable attains a truth value of true after all the desired
output are printed.
Program 4.6[Correct].cpp
By: Asaye Chemeda Email: asayechemeda@yahoo.com 61
In the program, the statement on line 9 clears all
ajustfield flags and sets the left flag to be the
used as a justification flag for the outputs. By default,
C++ outputs are right-justified, i.e., they are written on
the right hand side of the allocated space. As can be seen
from output of program 4.5, all the outputs are printed on
the right hand side of the allocated space. However setting
the left flag puts them on the left hand side of the
allocated spaces and the unoccupied spaces will be shifted
to the right side. Which means that characters used as an
argument of fill function will be on the right hand side.
On line 10, the showpoint and showpos flags were
combined using the OR operator and passed as an
argument to setf function. Therefore, after this line
trailing zeroes will be displayed and the + sign will be
shown for positive values.
On line 23, the value of isPrintComplete is
changed to true. On line 24, the value this Boolean
variable is printed. Normally, C++ programs consider
Boolean variables to be 1 for true and 0 for false.
Since the value of isPrintComplete at the time of
its printing is true, the cout statement displays 1 and
the showpos flag set on line 10 adds a + sign before the
value. If it is desired to print the value of
isPrintComplete as ‘true’ or ‘false’, the
boolalpha flag should be set.
The output for program 4.6 is shown below. The outputs
are left-justified, the empty spaces on the right hand side
are filled, the + sign is added and the trailing zeroes are
displayed.
Let us consider again the Program 4.6 where the left,
showpoint and showpos flags are substituted by
hex and scientific flags. Since the hex and oct
flags operate only on int data types, two arrays, one with
int data type and another with float data type, were
declared. On the other side, the scientific flag
operates only on floating-point data types.
Program 4.7[Correct].cpp
On line 8 of the program, all the flags corresponding to
basefield are cleared first and the hex flag is set.
Therefore, integer values will be displayed in hexadecimal
numbers. On line 9, the scientific flag is set. Note
that, the floatfield flag group could also be used as
a second argument on line 9. However, mentioning the
second argument is mandatory only when it is desired to
clear all the previous settings for the flags corresponding
to the group.
The outputs will now be displayed in three columns. The
second column displaying the output of an int data type
price array whereas the third column displays the
output for float data type price2 array.
The boolalpha flag is now set on line 27 and the
output of the isPrintComplete variable on line 28
will be the keyword true.
The output of program 4.7 is shown below. In the output,
characters are right-justified, empty spaces are filled, int
data type values are displayed in hexadecimal numbers
and floating-point values are displayed in scientific
notation.
Once a flag is set, the setting can be reversed by using
unsetf function when the flag is no longer required or
By: Asaye Chemeda Email: asayechemeda@yahoo.com 62
to return to the default setting for that particular flag. The
syntax used for the unsetf function is the same as that
of setf function. The only difference is the unsetf
function is not overloaded to take two arguments. The
following statement reverses flag setting to the default
setting for outputs through ostreamObject.
For instance, the following statement clears the left-justify
setting and returns the justification setting to the default
setting.
The unsetf function also takes flags combined with
OR operator as an argument. In which case, all the flags
combined by the OR operator will be set to their default
setting. The following statement clears the showpoint
and showpos flags.
We have seen that by setting and unsetting different flags,
we can display outputs in different formatting styles.
Now, let us see the strong side of the functions in ios
class which cannot be attained by the formatting
functions in the iomanip file.
The main advantage of the flags in the ios class is that
they can be assigned to a variable with fmtflags data
type. Consequently, any particular flag setting which is
assigned to a variable can be used to set a flag anywhere
in the program by using the variable. Combined flags can
also be assigned to variable. The syntax to create a flag
variable is:
In the above declaration, a combination of flag1,
flag2 … flagN is assigned to variable f which is of a
fmtflags data type.
Once a flag variable is declared, it can be used at another
place of the program. For this, the flags function can
be used. The flags function is overloaded and it has
one of the following two forms:
The syntax given in Form 1 returns the current flag setting
of ostreamObject. Therefore, it can be assigned to
variable with fmtflags data type. The syntax given in
Form 2 sets the flag for outputs through
ostreamObject to flagVariable.
The following program shows how flag variables and the
flags function can be used.
Program 4.8[Correct].cpp
In the above program, the statement cout.flags()
on line 4 returns the current flag setting of the program
and assigns it to f1 variable. Since no flag was set in the
program before the statement on line 4, f1 will contain
the default flag setting. On line 5, another flag variable f2
was declared. This flag variable will contain the combined
showpoint, showpos and left flags.
On line 7, a minimum width of 10 is set for the output
on line 8. Note that, until line 8, the flag setting is the
default flag setting used by the compiler. Therefore, when
the value of 100.10 is printed by the cout statement
on line 8, it will be right-justified, and trailing zeroes will
be omitted.
On line 9, the flag setting is altered by using the flags
function to the flag settings contained by the f2 variable.
Again, the minimum width is set to 10 by using width
function on line 10. As a result, when the value of
100.10 will be displayed by the cout statement on line
11, it will be left-justified, trailing zeroes and the + sign
will be displayed.
On line 12, the f2 flag setting is cleared by using
unsetf function. Which means that when the value of
100.10 is printed, the default flag setting will be used.
The output of the above program will look like:
Controlling how the output is displayed through ios
class functions was exciting, right? Of course it was.
By: Asaye Chemeda Email: asayechemeda@yahoo.com 63
Besides, the formatting procedures are very applicable for
real world programming too. The ios class functions
have their strengths in being assigned to a flag variable.
Despite this, they have some shortcomings as well. The
main limitation of the ios class formatting functions is
that they have to be always written as a separate statement;
each statement requiring the output stream to invoke the
function. Which means that they cannot be embedded
within insertion operators where one output stream
invokes a number of functions. As a result, several lines
of coding is required making the program to be error
prone.
Don’t you think it is better if the functions could be
embedded within the insertion operators? Wouldn’t this
avoid several repetitions of separate invocations the
functions by the output stream? The ios class functions
would definitely be more versatile if they could be
embedded within the insertion operators. But, they
already have their strong sides. Their limitation is
possessed while their strong side is lost by the so called
manipulator functions in the iomanip file. Are you
ready to learn the functions in this file? As most of this
functions have an equivalent from the ios class,
understanding how the manipulator functions will be
used is very easy.
Formatting output using the manipulator functions
The iomanip file has a number of functions which can
be used change the formatting styles of an output. In
order to use these functions within a program the
iomanip file should be included in the program. Some
of the functions in this file along with the equivalent ios
class functions are listed below.
setw – allocates a specified number of character
spaces for an output. [Equivalent with width]
setprecision – puts the output in specified
number of decimal places. [Equivalent with
precision]
setfill – fills empty spaces of the allocated
character spaces for an output with designated
character. [Equivalent with fill]
setiosflags – sets a specific flag for an
output. [Equivalent with setf]
resetiosflags – reverses the flag set by
setf function. [Equivalent with unsetf]
endl – displays the next output on a new line.
All of the above functions are invoked by an output
stream (ostream class object) by using the insertion
operator. The way how the above functions are used in a
program is the same as the way how the equivalent
functions in the ios class are used. A significant
difference is the manipulator functions cannot be
assigned to a variable but the ios class functions can. In
addition, the manipulator functions can be concatenated
by using the insertion operator on a single output stream
whereas the ios class functions can’t. Therefore, no
further separate discussion will be made for each of the
functions. However, mentioning the flags in the
iomanip file is vital and the most frequently used ones
are listed below.
left – makes the output left-justified.
right – makes the output right-justified.
showpoint – enforces displaying of trailing zeroes.
noshowpoint – turns off the showpoint flag.
showpos – displays the + sign when positive numbers
are displayed.
noshowpos – turns off the showpos flag.
fixed – puts the output in fixed number notation.
scientific – puts a floating-point output in scientific
notation.
boolalpha – allows input and output of Boolean
values by using the keywords true and false.
noboolalpha – turns off the boolalpha flag.
dec – displays an output as decimal (base 10) number.
oct – displays an integer output as octal (base 12)
number.
hex – displays an integer output as hexadecimal (base 16)
number.
To see the equivalency between the manipulator
functions and the ios class functions, we will format the
output for Program 4.7 using manipulator functions.
When the output of Program 4.7 is entirely formatted by
the manipulator functions, the program will appear to be
as follows. Note that the iomanip file is included in the
program.
Program 4.9[Correct].cpp
By the statement on lines 9 and 10 of program 4.9, the
flags in basefield are turned off and the hex and
scientific flags are turned on. Notice how the
resetiosflags and the setiosflags are
By: Asaye Chemeda Email: asayechemeda@yahoo.com 64
concatenated using the insertion operator on a single
cout stream. In program 4.7, this was done by separate
statements.
The statements from line 10 up to line 15 of program 4.7
are combined by a single statement on line 11 of the
program resulting in the same effect on the output. Note
how the setw function replaced the width function for
the same arguments. Inside the for-loop, the statements
from line 17 through line 24 of program 4.7 are replaced
by a single statement on line 14 of program 4.9. The
setfill function inside the for-loop of program 4.9
replaced the fill function in program 4.7. The two
statements which were used to set the boolalpha flag
and display a Boolean variable in program 4.7 are now
reduced to a single statement line 18 of the program.
Note that the output of program 4.9 is displayed in exact
the same setting as that of program 4.7. However, the
possibility for concatenation of the manipulator functions
allowed to have fewer statements in program 4.9. This
shows the edge that the manipulator function have over
the ios class functions in having fewer number of
statements and therefore less error prone program.
However, if we refer program 4.8 and notice how the
functions in ios class can be assigned to a variable, we
understand that the ios class functions have an edge
over the manipulator function as well. This disadvantage
of the manipulator functions, however, can be improved
by defining sequence of manipulators. The syntax to
create such customized sequence of manipulators for an
output stream is:
The above syntax is just like defining a function which
returns and receives by reference in which ostream is
the return type of the function and the data type of the
parameter, name is the function name and variable
is the argument. The name and variable can be any
qualified identifiers. On the last line of the definition of
the sequence of manipulators, variable should be
returned. Within the body, any output formatting
operations by either the manipulator functions or the
ios class functions can be included considering
variable as an output stream.
Once the sequence of manipulators are created as above,
name can be used within extraction operators to enforce
the format settings included in the body of the definition.
Creating sequence of manipulators is helpful where the
same sequence of formatting operations are frequently
used in a program. This avoids repetitions of codes
making the program neater as well as less error prone.
The output setting achieved in Program 4.8 by assigning
flags to flag variables can exactly be replicated with the
following program.
Program 4.10[Correct].cpp
In the above program, two sequences of manipulators
customSetting and defaultSetting were
defined. The customSetting has the same setting as
flag variable f2 of program 4.8 with the exception that
customSetting allocates 10 character spaces for the
output. The customSetting turns on the
showpoint, showpos and left flags whereas the
defaultSetting does the opposite but it also
allocates 10 character spaces for the output.
The main function extends from line 18 to line 23 of the
program. On line 19, the value 100.10 is printed by first
invoking the defaultSetting sequence. The task of
this statement is just like printing the value with the
default compiler format setting except that the width is
set to 10. On line 20, the value 100.10 is printed by first
invoking the customSetting sequence. Since the
format setting in customSetting combines the
statements on line 9 and 10 of program 4.8, calling the
sequence will have the same effect on the output as the
mentioned lines of program 4.8. On line 21, the value
100.10 is printed by invoking the defaultSetting
sequence first. This will have the same effect as lines 12
through line 14 of program 4.8.
Note that within the defaultSetting and
customSetting sequences, ios class functions
could also be included. However, the above program was
By: Asaye Chemeda Email: asayechemeda@yahoo.com 65
intended to show how the shortcoming of the
manipulator functions can be improved by creating
sequence of manipulators. As a result, only manipulator
functions were used in the sequences.
Through the ios class and manipulator functions, we
have seen how outputs can be formatted using different
styles. Wasn’t it interesting? Indeed it was. But, they are
not the only functions used in C++ to format outputs.
C++ program has adopted another function from C to
format outputs with wide range of data types. This
function is versatile and discussing its application is very
useful.
The printf function
One of the derived functions from C program, printf,
can be used to print a formatted output to the console.
This function is best used when printing combination of
different output data with different format settings at
once is required. The function is overloaded to receive
different number and data types of arguments. In order
to use the function, the stdio.h file should be included
in the program.
The general syntax to use the printf function in a
program is:
In the above syntax, the formatSpecifier basically
contains one or more format specifiers along with other
characters. Each format specifier contains the percent
sign (%) followed by format code. The format code
depends on the data type which is going to be printed by
the function. Among many format codes, c stands for
characters, d for signed integers, f for floating point
values, s for strings, p for pointers, e for scientific
notation and x for hexadecimal numbers. The rest
arguments, variables, will contain the same number
of variables as the number of format specifiers. The
variables should be separated by a comma and placed in
the same order as the order of the format specifiers placed
within the first argument.
The following statement prints 1m on the screen.
The first argument in the above statement contains two
format specifiers, %d and %c. Therefore, two other
arguments matching these format specifiers. Since the
format code d stands for integers, the first argument after
the format specifier should be an integer. The other
argument should be a character as the format code c
stands for characters.
Other characters than the format specifiers can also be
included in the first argument of printf function. Let
us consider the following statement.
In the above statement, there are two format specifiers in
the first argument, %d and %s. The inclusion of additional
characters in the first argument is also legal. When the
output is displayed on the screen, the arguments outside
the double quotes will replace the places occupied by the
format specifiers. However, the arguments outside the
double quotes should be placed in the same order as they
are put in the first argument. An integer first and a string
next. The above statement displays the following on the
output.
As can be seen from the output, the second argument, 3,
replaced the %d specifier in the first argument and the last
argument, “C++” replaced the %s specifier.
The format setting for some data types can also be
adjusted by introducing numbers between the % sign and
the format code. These numbers can be a single integer
or two integers separated by a dot. The effect that putting
numbers between the % sign and the format code depends
on the data type. The number 0 can also precede the first
integer. The number between the % sign and the format
code is generally put as 0x.y, where x and y are integers.
The preceding 0 is used to fill empty character spaces with
0. The value of x represents the minimum allocated
character spaces for any data type. The meaning of y is
different for different data types. For integers, it
represents the minimum number of digits. If the integer
contains less digits that y, the 0 characters will precede
the number. For floating point data types, it represents
the number of digits after decimal places. For strings, it
represents the maximum number of characters.
The following statement displays the number
1298.567 with 9 character spaces and 2 digits after the
decimal point and fills any empty spaces with 0.
The output of the above statement is:
The following statement displays the number 1000 after
the string “Output” with 10 character spaces and 5
digits within the allocated character spaces.
By: Asaye Chemeda Email: asayechemeda@yahoo.com 66
The output for the above statement looks like:
When an output is displayed using the printf function,
it is right-justified. In order to display the output left-
justified, we need to put minus (-) sign just after the %
sign.
The following statement allocates a minimum of 15
character spaces and prints a maximum of 10 left-
justified characters from the “Programming” string.
The output of the above statement is shown below:
The above output is left-justified. Only 10 of the 11
characters in the string are printed in the 15 allocated
character spaces.
The printf function is very helpful in order to
concatenate a string message with variables of different
data types with a specified format setting. It avoids
invoking a number of formatting functions in the ios
class or iomanip file. For instance the following
program has a closer effect on the printing of price and
price2 arrays given in program 4.9.
Program 4.11[Correct].cpp
The statement on line 8 of the above program avoids the
multiple invocations of the setw function on line 11 of
program 4.9. Although filling the empty spaces with
designated characters could not be replicated, the
statement on line 11 of the program 4.11 again avoids the
multiple invocations of the setw function used on line
14 of program 4.9. The statement on line 14 of program
4.11 shows that how the printf function easily
integrates a string message with a variable used in the
program. This statement displays the number of items
printed by using the last value of the counter used in the
for-loop. When the above program is run, the displayed
output is:
Isn’t the printf function efficient in formatting
outputs? Of course it is. The way how the function
integrates a string message with other variables of
different data types is also superior to the functions in
iostream file or iomanip file. However, it has a
severe limitation. In contrast to the iostream file or
manipulator functions, which can display outputs to wide
variety of output devices, the printf function can only
display an output to an internal displaying device, which
is usually the screen.
Speaking of, we haven’t yet discussed about input and
output operations beyond the default input device
(keyboard) and output device (screen), right? However, at
the beginning, we have said that the input and output
streams in C++ can interact with any type of input or
output device. Among the many input or output devices,
however, using files as an input source or an output
destinations is frequent task which a programmer often
encounters. Therefore, it is worth discussing about how
input and output operations on files is done separately.
The next topic discusses this concept in detail.
File Input and Output (I/O)
Using files as an input source and an output destination
might sometimes become preferable to input and
operations on standard input and output devices. If an
input data involves several characters, using the keyboard
to enter the bulky data every time the program runs might
become tedious. In those cases, the input data may be
stored in files and the program can be made extract the
input from the file. This avoids the tedious typing process
and the accidental errors which may occur in doing so.
Displaying the output to the screen has also certain
limitations. First, the screen accommodates limited
number of characters for display. Therefore, when there
is a large data to display, the screen is unusable and using
files becomes very handy. Second, the outputs made on
the screen cannot be saved and cannot be used at a later
time or as an input for other applications.
Due to the above limitations of I/O operations on
standard devices, files are often used to read input from
and write an output to. Input and output operation on
files are much similar to those on standard devices. There
are notable distinctions though.
By: Asaye Chemeda Email: asayechemeda@yahoo.com 67
The input and output streams for I/O operations on
standard devices are created as soon as the program starts
execution. As a result, manual creation of the input and
output streams is not necessary. On the other hand, the
input and output streams to read data from or write to
files should be created manually within the program.
Creating these streams is not that difficult though.
Besides creating streams, another notable distinction
between the I/O operation on standard devices and files
is that both the input and output streams for file I/O
should be associated with the files which they operate on.
Otherwise, I/O operations on files and on standard
devices are much alike. In addition, most of the functions
which are used to integrate the streams with the program
for standard devices can be used for files as well.
As the iostream file handles the input and output
streams for I/O operations on standard devices, the
fstream file handles the input and output streams for
file I/O. Therefore, whenever file I/O operation exists in
a program, the fstream file should be included in the
program.
Typical file I/O operation involves the following four
steps:
1. Creation of a stream
2. Association of a file with the stream
3. Operation on the file
4. Dissociation of the file with the stream.
Each of these steps will be discussed one by one. In an
object-oriented approach, the first and the second steps
can be combined. Since this approach is not that
complicated either, it will also be included in our
discussions.
Creation of a stream
Three types of streams can be created for file I/O. An
input stream for input operations, an output stream for
output operations and an input/output stream for both
input and output stream operations. Each type of the
streams is created by declaring a variable with the data
type of the class corresponding to the stream. The class
corresponding to the input stream is ifstream.
Whereas, the class corresponding to the output stream is
ofstream. The fstream class corresponds to
input/output stream. Once a variable is declared with a
data type of these classes, it will be used as a stream like
the standard streams such as cin and cout. The name
of the variable can be any qualified identifier.
The syntax to create an input, output and input/output
streams is:
After the above declarations, inputStream will be
used as an input stream like cin to read data from files.
The outputStream can be used as an output stream
like cout to write data to files. The ioStream can be
used as both input and output stream to read from and
write to files.
The important property of file input and output streams
is that they can only interact with only one file at a time.
If the program requires to interact with more than one file
for either the input or the output stream at the same time,
the same number streams should be created and each of
them should be associated with a single file at a time. But,
an input or output stream can be used to interact with
another file after being dissociated with the first file.
Association of a file with a stream
Another important step in file I/O is associating each
stream with the file with which it interacts with. The input
stream should be associated with the file from which data
is read. The output stream should be associated with the
file to which a data will be written. This can be done in
one of the two approaches available in C++. The first one
is by using the open() function. The second approach
is including the file name during the stream itself. The
syntax for both approaches is shown below.
The above approach uses the open() function to
associate the file which has fileName with the
corresponding stream.
The above approach simultaneously creates streams and
associates them with the file which has fileName.
If the file is not in the same directory as the directory
which the program points to, the full path should be
mentioned with fileName. If a file with a specified file
name is not available in the directory, the input stream
leads to a program in fail state while the output stream
creates a new. Therefore, including a code which checks
the availability of the file with the specified file name in
the program is important to avoid a possible input stream
failure. When an output stream interacts with an existing
file as shown above, it first erases all the data in the file.
By: Asaye Chemeda Email: asayechemeda@yahoo.com 68
Operation on the file
Once a file is associated with a stream, any valid operation
can be performed on the data extracted from the file. The
output results can be send to a file. Suitable formatting
styles can also be applied to the output. For this, the
functions in the iostream class or fstream class can
be used. In general, after associating a file to a stream, the
normal C++ procedures can be applied with the data
extracted to the program as an input and to the data sent
to the destination as an output. The functions which are
peculiar to file I/O will be discussed briefly while the
functions which are used for I/O operation on standard
devices will be reviewed.
Dissociation of a file from the stream
After the necessary I/O operation is performed on files,
they should be dissociated from the stream. This may
have several advantages. First, the stream which is
dissociated from a file can be used for another I/O.
Second, the dissociation flushes any remaining data in the
stream and the file can be used for further activities.
The dissociation of files from a stream is done by using
the close() function. This function doesn’t take any
arguments. It is invoked by the stream for which the
dissociation is going to be done with the member access
operator. The syntax to dissociate a file from an input,
output and input/output streams is:
We have covered the basic steps in file I/O. It was
fascinating! Wasn’t it? File I/O is as interesting as I/O
operation to standard devices. Now, let us discuss the
functions which are often used in file I/O.
The open function
We have seen that the open function is used to associate
a file with the stream. Here, we will discuss the features
of the function which were not discussed before.
After an input stream invokes open function, the stream
may evaluate true in Boolean expressions if the file which
is passed as an argument exists and EOF is not reached
in the file or false otherwise. Thus, the input stream can
be used in a code that checks whether the file exists or not
so that further actions can be taken depending on the
outcome. At the same time, the input stream returns true
when the EOF is not reached or false otherwise. This
concept can be used as a logical expressions so as to limit
the input stream from trying to extract data beyond EOF.
The open function actually takes two arguments. The first
argument is always the file name. Whereas, the second
argument is a parameter which describes the mode how
the file will be opened. In the function definition, the
second argument is initialized in the formal parameter list.
As a result, passing the second argument is optional. A
number of alternatives are available for the mode. These
alternatives are listed as follows along with their
explanation.
ios::in – specifies that a file is capable of input.
ios::out – specifies that a file is capable of output.
ios::app – appends an output to the existing data in
the file. It is used for output capable of output only.
ios::ate – points to the end of file (EOF) when the
file is opened.
ios::binary – opens the file in binary mode.
ios::trunc – erases all the data in the existing file.
The above modes can be combined with the OR operator
in order to have more than one effect. The default values
for this modes are ios::in for ifstream,
ios::out|ios::trunc for ofstream
ios::in|ios::out for input/output fstream. If
instead of the default second argument for ofstream,
the ios::app is used with any other mode but the
ios::trunc, the existing data in the file will be
preserved during output.
Let us now consider the following program to see how
creation of streams, association with streams, working on
the files and dissociation is done.
Program 4.12[Correct].cpp
In the above program, the fstream file is included on
line 2. On line 5, an input stream input is created. On
line 6, an output stream output is created. After that,
on line 7, input is associated with a file name
Input1.txt. This file exists in a directory named
files which by itself exists in the working directory of
the program. Therefore, the whole path is passed as an
argument during the association. Note that two back-
By: Asaye Chemeda Email: asayechemeda@yahoo.com 69
slashes are required to change directory: one the escape
operator the other the actual back-slash.
On line 8, output is associated with a file named
Output1. This file exists in the same directory as
Input1. Two arguments are passed for the open
function during the association. The second argument
ios::app overrides the default arguments
ios::out|ios::trunc. As a result, when an
output is sent to the output file, the original content will
not be erased. Rather, an output will be appended to the
existing data.
The if-statement between line 9 and 11 checks whether
the Input1 file exists or not. If the file exists in the
specified directory, input will evaluate true.
Otherwise, it evaluates false. If the case is the latter
one, the program displays the message “The file
doesn’t exist!”.
On line 12, the first data is sent to the output file by using
the insertion operator on output. The string “The
first output message!” will be sent to the file.
If the output file has already other data, the string will be
appended to the existing data. This is due to the second
argument passed to the open function. On line 13, the
string “This one is appended!” will be appended
to string sent on line 12.
On lines 14 and 15, input and output are dissociated from
the files which they have been interacting with. After this,
the streams can be associated with other files for further
I/O operations.
Isn’t file I/O so simple? It even makes the basic principle
of C++ I/O operations more clear. Do you also feel the
same? Or do you want to wonder more? Let us now have
a look at other functions which are frequently used in file
I/O. In program 4.12, we have seen how the existence of
an input file is checked by using the input stream itself.
There is also another way to do this. In addition, what if
we want to check an output file exists or not. The
identifier of an output stream cannot be used in the same
way as the identifier of the input stream was used to check
whether an output file exists or not. In those cases, C++
has a built-in function which checks the existence of an
input file. This function will be the next topic.
The is_open function
A member of the fstream, ifstream and
ofstream classes, is_open function, checks whether
a stream is associated with an existing file or not. It works
with any stream and is invoked by the stream using the
member access operator. The function takes no
arguments returns true if the stream is associated with an
existing file or false otherwise. The syntax to use the
function is:
In the above statement, the is_open function returns
true if stream (which can be any stream) is associated
with an existing file or false otherwise.
Once we have seen how we can check whether a file exists
or not, let us focus on the functions which are often used
for operations on files. One of the most frequent
operations on input files is to check whether the end of
the file (EOF) is reached or not during extraction.
Because extracting data from input file usually takes place
until EOF is reached. One of the ways to do this is to use
the input stream identifier in a logical expression. But, is
there another way? The following topic answers this.
The eof function
A member of the ios class, eof function, returns true
when end of file is reached or false otherwise. The
function is invoked by a stream with the member access
operator. The syntax to use the eof function is:
The above statement will evaluate to true when EOF is
reached in the file associated with stream. Therefore, an
input stream should only extract as long as negation of the
above statement returns true.
Since an attempt by a program to perform input operation
beyond EOF results in an error, detecting whether an
EOF is reached or not is a common activity in dealing
with reading data from files. Normally, the I/O operation
on files takes place in sequential order. But, what if we are
interested to point to specific location where the next I/O
operation will take place within a file? Or what if it is
desired get the current location where I/O operation is
taking place? The next topic gives clues about these.
The seekg,seekp,tellg and tellp functions
The seekg and seekp functions respectively are
members of the ifstream and ofstream classes
which are used to point a specific location in the files
associated with the respective streams. The seekg
function is called get pointer and the seekp function is
known as put pointer. Both the functions take two
arguments. In both functions, the first argument specifies
an integer offset from the file location specified in the
second argument. The value offset represents the number
of bytes to be passed from the location specifier to the
next point. The syntax for the functions is as follows:
Input and output in c++
Input and output in c++

More Related Content

What's hot (20)

Assignment2
Assignment2Assignment2
Assignment2
 
Ch02
Ch02Ch02
Ch02
 
Constants Variables Datatypes by Mrs. Sowmya Jyothi
Constants Variables Datatypes by Mrs. Sowmya JyothiConstants Variables Datatypes by Mrs. Sowmya Jyothi
Constants Variables Datatypes by Mrs. Sowmya Jyothi
 
Ch04
Ch04Ch04
Ch04
 
Assignment5
Assignment5Assignment5
Assignment5
 
Cpu-fundamental of C
Cpu-fundamental of CCpu-fundamental of C
Cpu-fundamental of C
 
Strings-Computer programming
Strings-Computer programmingStrings-Computer programming
Strings-Computer programming
 
Ch08
Ch08Ch08
Ch08
 
Computer experiments 1^j2^j3^j4^j8^j9. d24 ^j sakshi gawade cs branch
Computer experiments   1^j2^j3^j4^j8^j9. d24 ^j sakshi gawade cs branchComputer experiments   1^j2^j3^j4^j8^j9. d24 ^j sakshi gawade cs branch
Computer experiments 1^j2^j3^j4^j8^j9. d24 ^j sakshi gawade cs branch
 
Getting Started with C++
Getting Started with C++Getting Started with C++
Getting Started with C++
 
Overview of C Mrs Sowmya Jyothi
Overview of C Mrs Sowmya JyothiOverview of C Mrs Sowmya Jyothi
Overview of C Mrs Sowmya Jyothi
 
Python Objects
Python ObjectsPython Objects
Python Objects
 
Lab6: I/O and Arrays
Lab6: I/O and ArraysLab6: I/O and Arrays
Lab6: I/O and Arrays
 
C intro
C introC intro
C intro
 
Functions-Computer programming
Functions-Computer programmingFunctions-Computer programming
Functions-Computer programming
 
Assignment4
Assignment4Assignment4
Assignment4
 
Ch05
Ch05Ch05
Ch05
 
Conditional Statements
Conditional StatementsConditional Statements
Conditional Statements
 
Function
FunctionFunction
Function
 
Ch03
Ch03Ch03
Ch03
 

Similar to Input and output in c++

C5 c++ development environment
C5 c++ development environmentC5 c++ development environment
C5 c++ development environmentsnchnchl
 
Stream Based Input Output
Stream Based Input OutputStream Based Input Output
Stream Based Input OutputBharat17485
 
IIM.Com-FIT-Unit2(14.9.2021 TO 30.9.2021).pptx
IIM.Com-FIT-Unit2(14.9.2021 TO 30.9.2021).pptxIIM.Com-FIT-Unit2(14.9.2021 TO 30.9.2021).pptx
IIM.Com-FIT-Unit2(14.9.2021 TO 30.9.2021).pptxrajkumar490591
 
Introduction to Data Structure
Introduction to Data Structure Introduction to Data Structure
Introduction to Data Structure Prof Ansari
 
Sample for Simple C Program - R.D.Sivakumar
Sample for Simple C Program - R.D.SivakumarSample for Simple C Program - R.D.Sivakumar
Sample for Simple C Program - R.D.SivakumarSivakumar R D .
 
Basic Concepts in Python
Basic Concepts in PythonBasic Concepts in Python
Basic Concepts in PythonSumit Satam
 
Basics Of C++.pptx
Basics Of C++.pptxBasics Of C++.pptx
Basics Of C++.pptxDineshDhuri4
 
Ap Power Point Chpt2
Ap Power Point Chpt2Ap Power Point Chpt2
Ap Power Point Chpt2dplunkett
 
Java Input and Output
Java Input and OutputJava Input and Output
Java Input and OutputDucat India
 
File handling in_c
File handling in_cFile handling in_c
File handling in_csanya6900
 

Similar to Input and output in c++ (20)

L4.pdf
L4.pdfL4.pdf
L4.pdf
 
Managing console input
Managing console inputManaging console input
Managing console input
 
C5 c++ development environment
C5 c++ development environmentC5 c++ development environment
C5 c++ development environment
 
Intro To C++ - Class 14 - Midterm Review
Intro To C++ - Class 14 - Midterm ReviewIntro To C++ - Class 14 - Midterm Review
Intro To C++ - Class 14 - Midterm Review
 
Stream Based Input Output
Stream Based Input OutputStream Based Input Output
Stream Based Input Output
 
IIM.Com-FIT-Unit2(14.9.2021 TO 30.9.2021).pptx
IIM.Com-FIT-Unit2(14.9.2021 TO 30.9.2021).pptxIIM.Com-FIT-Unit2(14.9.2021 TO 30.9.2021).pptx
IIM.Com-FIT-Unit2(14.9.2021 TO 30.9.2021).pptx
 
Bitstuffing
BitstuffingBitstuffing
Bitstuffing
 
Bcsl 031 solve assignment
Bcsl 031 solve assignmentBcsl 031 solve assignment
Bcsl 031 solve assignment
 
Introduction to Data Structure
Introduction to Data Structure Introduction to Data Structure
Introduction to Data Structure
 
Iostream in c++
Iostream in c++Iostream in c++
Iostream in c++
 
Sample for Simple C Program - R.D.Sivakumar
Sample for Simple C Program - R.D.SivakumarSample for Simple C Program - R.D.Sivakumar
Sample for Simple C Program - R.D.Sivakumar
 
Basic Concepts in Python
Basic Concepts in PythonBasic Concepts in Python
Basic Concepts in Python
 
Basics Of C++.pptx
Basics Of C++.pptxBasics Of C++.pptx
Basics Of C++.pptx
 
Oodp mod4
Oodp mod4Oodp mod4
Oodp mod4
 
Ap Power Point Chpt2
Ap Power Point Chpt2Ap Power Point Chpt2
Ap Power Point Chpt2
 
C-PROGRAM
C-PROGRAMC-PROGRAM
C-PROGRAM
 
Java Input and Output
Java Input and OutputJava Input and Output
Java Input and Output
 
C Programming Unit-1
C Programming Unit-1C Programming Unit-1
C Programming Unit-1
 
File handling in_c
File handling in_cFile handling in_c
File handling in_c
 
C program
C programC program
C program
 

Recently uploaded

Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about usDynamic Netsoft
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝soniya singh
 
Engage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyEngage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyFrank van der Linden
 
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfkalichargn70th171
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEOrtus Solutions, Corp
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideChristina Lin
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio, Inc.
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantAxelRicardoTrocheRiq
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityNeo4j
 
XpertSolvers: Your Partner in Building Innovative Software Solutions
XpertSolvers: Your Partner in Building Innovative Software SolutionsXpertSolvers: Your Partner in Building Innovative Software Solutions
XpertSolvers: Your Partner in Building Innovative Software SolutionsMehedi Hasan Shohan
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWave PLM
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxTier1 app
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxbodapatigopi8531
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...gurkirankumar98700
 

Recently uploaded (20)

Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about us
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
 
Engage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyEngage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The Ugly
 
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service Consultant
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered Sustainability
 
XpertSolvers: Your Partner in Building Innovative Software Solutions
XpertSolvers: Your Partner in Building Innovative Software SolutionsXpertSolvers: Your Partner in Building Innovative Software Solutions
XpertSolvers: Your Partner in Building Innovative Software Solutions
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need It
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
 

Input and output in c++

  • 1. By: Asaye Chemeda Email: asayechemeda@yahoo.com 46 CHAPTER FOUR INPUT AND OUTPUT IN C++ Introduction Most C++ program applications involve three basic stages: input, analysis and output. In the previous chapters, all these stages were included in the programs we wrote. We used several input as well as output statements to read data into our program and to display results on the screen. However, no emphasis was given on the way how data input or output took place. This chapter is devoted to analyze how input and output processes take place in a C++ program and how the data can be formatted and manipulated. Input and output of data can take place from the default devices. The default input device is the keyboard while the default output device is the screen. Besides, the input and output of data can also take place from other sources or destinations such as files. In this chapter, input and output procedures to both default devices and files will be discussed. Whichever the source or destination is, the input output in C++ is based on a concept known as stream. Discussing about streams is vital for detailed understanding of how input and output data can be formatted and manipulated. Therefore, streams will be the first topic in this chapter. Stay tuned till the end of the chapter and you will love what we are going to discuss. C++ Streams What comes to your mind when you think of the word ‘streams’? A flow of water, right? Good imagination. Now think of two places in which water flows from the first to the second delivering goods in its direction of flow. Streams in C++ are just like the flow of water between the two points. They deliver data from input source to your program or from your program to the destination. In a water flow, it is the water which delivers goods. In C++ streams, it is the sequence of bytes which delivers the data. The sequence of bytes can be in a text or a binary form. However, most C++ applications use the text form of bytes which are characters. In short, streams are interfaces through which sequence of characters is transferred from a source to a destination. A typical program reads data and displays the result. If so, how many type of streams do we normally need to write a program? Two, right? One of the streams conveys data from an input source such as keyboard to the program. The other stream conveys from your program to output destination such as screen. Those streams through which data is conveyed from input source to a program are called input streams while the streams conveying data from a program to a destination are called output streams. A stream may not only contain a single data at a certain instance. A sequence of characters corresponding to a number of data may be temporarily lined up in a stream. In such cases, the data in the stream is said to be buffered data. You may raise an interesting question here. How do the sequence of characters in the streams interact with a program? Let me ask you a question before we answer this. In almost all of the programs we wrote, we included the <iostream> header file. Why do you think we did that? It is because files like <iostream> have functions which interact with streams. These functions interpret the sequence of characters in the streams and convey it to the appropriate variable in a program or the other way round. Therefore, streams interact with programs through pre- defined functions. The flow of data from a keyboard to a program and from program to screen is pictorially represented below. The <iostream> file contains entities called classes that contain functions which interact with the input stream and output streams. The class which contains functions which interact with input stream is called istream. The class which contains functions which interact with output stream is called ostream. In addition, the <iostream> file contains a class called ios. This class contains some of the variables and operations for both input and output (I/O) operations. To get access to the operations and functions in the istream or ostream class, you need objects of the classes. The objects are like blue prints of the class which have the privilege to access the accessible members of the class. For example cin is an object of istream and cout is an object of ostream. The objects cin and cout are built-in streams for input and output operations respectively. When a C++ program begins execution, four built-in streams will be opened automatically. These streams are
  • 2. By: Asaye Chemeda Email: asayechemeda@yahoo.com 47 cin, cout, cerr and clog. The cin and cout are standard input and output streams respectively. Whereas the cerr and clog are output streams for standard error output and buffered error output respectively. Some of the functions in istream or ostream classes are invoked through the member access operator while others are invoked with different operators. The member access operator is a dot (.) while the other operators are the extractors (>>) and inserters (<<). The relevant functions in the <iostream> file will be discussed next. Note that, whenever we want to use operations and functions in istream , ostream or ios classes, the file <iostream> should be included in our program. The inserter functions The inserter functions are overloaded functions which insert data obtained from the program into the output stream through the insertion operator (<<). This operator is a binary operator which takes two operands. On the left side, it takes ostream class objects, i.e. output streams, such as cout and on the right hand side it takes variables of designated data type. The extractor functions are overloaded so that any type of ostream object and any data type can be used as operands. The inserter functions are also overloaded to insert any number of variables into a single output stream. The general form of inserter functions is as follows: The extractor functions The extractor functions are overloaded functions which extract data from the input stream and pass it to the program through the extraction operator (>>). This operator is a binary operator which takes two operands. On the left side, it takes istream class objects, i.e. input streams, such as cin and on the right hand side it takes variables of designated data type. The extractor functions are overloaded so that any type of istream object and any data type can be used as operands. The general form of extractor functions is as follows: As shown in the above syntax, the extractor functions are also overloaded to extract any number and data type of variables with a single istream object. Some of the rules to be followed for the extractor operator are given below. Rule 1: During extraction, any preceding white spaces and new lines before any of the variables are skipped. Rule 2: Extraction takes place until a white space or an input with a different data type than the data type with which the variable is declared is encountered. Rule 3: When an extractor encounters a different data type than the variable for which it is going to extract value from the input stream without extracting any value prior to the encounter, the program will be in fail state and any further input operations in the program will be aborted. Rule 4: When an extractor encounters an input with a different data type than the variable for which it is going to extract value from the input stream after some extraction was made, the extraction will be terminated and the variable will be assigned with extracted value before the encounter. The rest data will be held in the input stream waiting for the next input operation. Rule 5: After completing the extraction, an extractor function leaves a white space. What did you feel when you read the above rules? Same old same old? Or interesting? Anyways, we will see how the above rules may resolve some tricky problems in programs. Don’t you feel it is high time to write a program to have a look at the implementation of the above rules? Let us write one then. Note that, we are not going to write a complicated program for this. It is the data which we input which will make us realize how the above rules are applied. Program 4.1[Correct].cpp
  • 3. By: Asaye Chemeda Email: asayechemeda@yahoo.com 48 The above program is simple, right? Two int variables x and y, one double variable z, one character variable c and one string variable s are declared. All the variables except s were read with overloaded extraction operator on line 11. Then the string variable is read on line 13. On the subsequent lines, the entered values are printed. As we said, it is not the program which matters. It is the data we enter. Now, let us see what the output will be for different input data. First run, Even if there were white spaces before the first input (10) and the last input (12.76) on Input line 1, the values of x and z are 10 and 12.76 respectively. Because any preceding white spaces before the input data were skipped (Rule 1). Even if the string input on Input line 2 is “C++ is fun!”, only the string “C++” is assigned for s. This is because, extraction took place only until a white space was encountered. (Rule 2). Note that, the input stream still contains the string “is fun!” which is a left over from the extraction on line 13. Second run, While the first variable to be extracted is supposed to be an integer, a character ‘B’ is the first input entered on Input line 1. When the first extraction operation encounters this and fails to extract the right value for the int variable x, the program will be in fail state. All the extractions after the encounter and any further input operations were aborted. (Rule 3). No matter what values were extracted after this, we will not get the results which we expect. The displayed results also signify this. Third run, A continuous combination of characters were entered on Input line 1. Since the first variable in the cin statement on line 11 is an integer, the extraction continued until a value with another data type, i.e., character H, is encountered. (Rule 4). The integer value before the character, 13, is extracted and assigned to the value of x and the rest values will be held for another input operation. Note that, had there been no integer before the character H, the program would be in fail state. The next input operation is an extraction which attempts to assign a character variable c. Since any entered character corresponding to the ASCII list of characters can be considered as a char data type, the first character in the held values, i.e., H will be extracted as a value of c. Since a char variable only takes one character, the set of characters after H will be held in the input stream. The next extraction will attempt to extract the left over in the input stream and assign to the next variable which is an integer. Since the next integer until a non-integer character is encountered is 2091, this value will be extracted as a value of y. Again, the rest values will be held in the input stream and the extractor attempts to extract them to a double variable. Since the dot character is part of a floating point value and since the other held values are numbers, all the remaining values will be extracted to z. Note that, the dot character is not part of an integer data type. If the extractor finds the dot character for the first time and has to assign the values after the dot to an int data type variable, the program will become in fail state. The white spaces preceding the string in the Input line 2 were skipped and only the string before another encounter of a white space, i.e., “Object-Oriented” was assigned to the string variable s. The string after the white space, “Programming” will be held in the input stream. The way how Rule 5 works is best elaborated with other istream class functions and its discussion will be put off until we discuss those functions. What did you observe as strong sides of the insertion and extraction operators? Definitely, it is their flexibility to handle various forms of data. Do you agree? I hope you do. The inserters and extractors are overloaded functions and we have seen that they are very flexible in inserting or extracting any of the basic data types in addition to string variables. Besides, they can handle as many data as possible for a single input or output stream. Despite the above strong sides of them, however, we have also noted some of the shortcomings of the extractors.
  • 4. By: Asaye Chemeda Email: asayechemeda@yahoo.com 49 Could you guess the main drawback of the extractors? It is the way they handle white spaces. They simply skip them and ignore any data after white spaces. However, white spaces may be part of the data and the data after white spaces may be part of the data too. In such cases, where white spaces or the data after them are important, the istream and ostream classes have rich set of functions. These functions will be discussed in the subsequent topics. The put and get functions The put and get functions are members of the ostream and istream classes. The put function is used to convey a single character at a time to the output stream whereas the get function extracts a single character at a time from the input stream to a program. Note that, the characters may also include white spaces, tab and new line characters. Both functions are invoked by applying the member access operator on the output or input streams. The general form of the put function is given below. The above statement will send a char data type characterVariable into the output stream. Note that, the argument of put function can be a char data type variable, a character literal or an integer corresponding to the equivalent ASCII value for a character. For instance, the following three cout statements display the character A on the output device. The statement on Line 2 inserts the value of the cVar variable to the output stream. The statement on Line 3 delivers the character A to the output stream. The statement on Line 4 delivers the character with ASCII number of 65. The get function has many forms. The frequently used ones are the following: The syntax given in Form 1 extracts a char variable from the input stream and assigns the value to characterVariable. The get function given in Form 2 extracts a maximum of number-1 characters from the input stream and assigns the extracted characters to characterArray which will be null-terminated by the function. The extraction will also be terminated when a new line character is encountered. The encountered new line will not be removed from the input stream. The get function given in Form 3 extracts a maximum of number-1 characters from the input stream and assigns the extracted characters to characterArray which will be null-terminated by the function. The extraction will also be terminated when a new line character or a character the same as delimiter is encountered. The encountered new line or delimiter will not be removed from the input stream. The get function given in Form 4 with empty parameters extracts the next character in the input stream. The return value of the function can be assigned to a character variable. When a program reaches statements like the above get forms, it extracts one or more characters from the input stream, if there is any, until the condition for terminating the extraction is filfilled. Otherwise, the program waits until a user enters a value. The following two statements assign the character variable cVar with the next character in the cin stream. Even if the above get form and put functions only hand one character at a time, suitable loops can be used to navigate through a large number of characters. The following statement extracts characters until new line character is encountered or a maximum of 99 characters are extracted and assigns the characters to cArray. By the process, cArray will be null-terminated. The following statement extracts characters until new line character is encountered or a dot is encountered or a maximum of 19 characters are extracted and assigns the characters to cArray. By the process, cArray will be null-terminated. Let us see the implementation of these functions in a program.
  • 5. By: Asaye Chemeda Email: asayechemeda@yahoo.com 50 Program 4.2[Correct].cpp In the above program, a character variable c and a string variable str were defined on lines 6 and 7. The string variable is read with an extraction operator on line 9. If the data which we entered for str contains internal white spaces, any characters after the first internal white space will be held in the input stream. (Rule 2 of extraction operator). The next input operation will then start extracting the left overs. Since the next input operation is the cin statement on line 14, the held characters will be extracted by the get function one by one until a new line character is encountered. The continuation of the extraction until new line character encounter is because the criteria for the termination of the do-while loop is so. Now, let us enter “C++ is fun!” as an input. The set of characters until the first white space, i.e., “C++” will be assigned to str variable. Each of the rest characters, i.e., “ is fun!” will be extracted by the cin.get(c) statement and printed by the cin.put(c) in the do- while loop. The output when the above string is entered looks like: By the way, what do you think will happen if we enter a string with no spaces? All the characters in the string will be assigned to the str variable, right? The interesting question is: what will be read by the cin statement on line 14 if all the characters are assigned to str? Will the program wait until we enter a value? If you answer this correctly, it means that you have remembered Rule 5 of the extractor function. Even if a string with no white space is entered, the extraction operator leaves a white space after it extracts. That white space will be extracted by the cin.get(c) statement on line 14 and the program will not wait for us to enter a character. Reading and writing any characters including white spaces, tab and newline characters were the strong sides of put and get functions. Did you notice that they have major drawbacks too? It is obvious, the main drawbacks of the put and get functions are the fact that they can only handle one character at a time and that they only interact with character variables. The first drawback can be solved if there are functions which read or write a number of characters at a time. Such functions are discussed next. The getline,read and write functions These functions are members of the istream and ostream class which read or write one or more characters in a single line. The getline function is invoked by input streams while the write function is invoked by output streams with a member access operator. The getline function extracts characters from the input stream and assigns them to a character array variable or a string variable. When the extracted characters are assigned to a character array variable, the null character is automatically appended to the character array. The getline function may have one of the following three forms: The statement in Form 1 is used to extract characters from istreamObject and assign the characters to the characterArray. The rules for the extraction are: Rule 1: The extraction continues until number-1 characters are read or new line character is encountered whichever comes first. Rule 2: If a new line character is encountered before reading number-1 characters, the extracted characters will be assigned to the characterArray. Rule 3: If there are more than number-1 characters in the input stream and the newline character is not yet encountered, the program will become in fail state. Rule 4: Null character is automatically appended at the end of the characters. The statement in Form 2 is used to extract characters from istreamObject and assign the characters to the characterArray. The rules for the extraction are:
  • 6. By: Asaye Chemeda Email: asayechemeda@yahoo.com 51 Rule 1: The extraction continues until number-1 characters are read or a character the same as delimiter is encountered or new line character is encountered whichever comes first. Rule 2: If a new line character is not encountered before reading number-1 characters, and if a character the same as delimiter is encountered, the extracted characters before the delimiter will be assigned to the characterArray. The delimiter is extracted from the input stream but it will not be included in the characters assigned to the characterArray. Rule 3: If a new line character is encountered before reading number-1 characters, and a character the same as delimiter is not yet encountered, the program will become in fail state. Rule 4: If there are more than number-1 characters in the input stream and the newline character or the delimiter is not yet encountered, the program will become in fail state. Rule 5: Null character is automatically appended at the end. However, if a character the same as the delimiter is encountered, a white space but not a null character is appended. The statement in Form 3 is used to extract characters from istreamObject and assign the characters to the stringVariable. The extraction continues until new line character is encountered. The read function extracts characters arrays from an invoking input stream. The general form of the read function is: In the above statement, the read function extracts length number of characters from istreamObject and assigns to characterArray. The extraction continues until length number of characters are extracted. The write function inserts characters arrays to an invoking output stream. The general form of the write function is: In the above statement, the write function inserts length number of characters from characterArray into ostreamObject. The insertion continues until length number of characters are inserted even if a null character is encountered. A number of write functions can be concatenated on a single output stream. The concatenated form of the write function is given for the cout output stream as follows: We haven’t yet looked into any specific statements for C++ programs using the getline and write functions. Once we know how they are invoked and what arguments they take, it is not that difficult to write few statements though. The following program shows the implementation of the functions in a program. Recalling about how dynamic arrays are created might be necessary for complete understanding of the program. Program 4.3[getline skipped].cpp In the above program, an int variable len, a character array c and a string pointer p were declared on lines 6, 7 and 8 respectively. The variable len will be used to store the size of a dynamic string array which is going to be created. The pointer p will be used to create the one- dimensional dynamic string array with a size of len. On line 9, the user is prompted to enter the length of the string array, i.e. the value of len. This value is read with the extraction operator from the cin stream on line 10. Due to the statement on line 11, a dynamic memory for len number of string variables will be allocated at run- time and the base address will be passed to the pointer p. The user is prompted to enter len number of strings on line 12. The for-loop from line 13 through line 15 extracts a line of string from the cin stream and assigns to each row of the dynamic array. The for-loop between line 17 and 19 will display these strings using the insertion operator.
  • 7. By: Asaye Chemeda Email: asayechemeda@yahoo.com 52 On line 20, the user is again prompted to enter a character array. By the statement on line 21, a maximum of 9 characters will be extracted from the cin stream by the first form of the getline function and will be stored into the character array c. Two concatenated write functions on line 22 will insert 7 characters from the string “Output:” and 9 characters from the c into the cout stream. On line 23, the user is prompted to enter a character array with a comma. The comma will be used as a delimiter. On line 24, the second form of the getline is invoked by cin to extract a maximum of 9 characters from the invoking stream and assign it to c. if the line of characters contain a comma within the first 9 characters, the extraction will be terminated. Another concatenated write function similar to the one on line 22 is used to insert the new value of c to cout stream so that it will be displayed on the screen. Now, let us run the program and enter the required data and analyze the output. Here is an output from a sample run. In the above sample run, the length of the string or the value of len is entered to be 3. After this, the program prompted us to enter 3 strings. Let us enter “Input stream” as the first string, “Output stream” as the second string. But when we were ready to enter the third string, the program did not let us. It just printed the two strings which were entered. The value of len is 3 and we expected the program to wait for us until we enter 3 strings; each followed by pressing the ‘Enter’ key which creates a new line character. But, why did the program not let us to enter the third string? Is there anything wrong with the for-loop? Did we make it loop only two times? No. It loops three times. Did we introduce a newline character in the middle of the strings we entered and the getline function picked two strings within a single loop? No. We introduced the new line character only at the end of the strings we entered. What is going on then? Recalling Rule 5 of the extractor function will solve the mystery. The rule says the extractor operator (>>) leaves a white space after extracting in the input stream. Now, let us look at line 10 of the program. The extractor operation is used to extract the value of len from the cin stream. Which means that according to the rule, there white space is still there in the cin stream after the statement on line 10. During the first loop of the for-loop between lines 13 and 15, the getline function on line 14 gets this white space in the cin stream and the newline character after that. As a result, the getline function will not make the program wait for us to enter a character during the first loop. It already assigned the white space in the cin stream as the first row of the dynamic array. What happened after this? Only two loops were remaining and the program waited for us to enter only two strings for the second and third rows of the dynamic array. Now, look at the output. There is a white space between the phrase “The printed strings are:” generated by line 16 of the program and the print of the first string we entered. This white space is the first row of the dynamic array. After this, the program prompted us to enter a character array to be extracted by another form of getline function on line 21. Since the maximum number of characters which this getline function call extracts is 9 (=10-1), we entered the string “Iostream” which has 8 characters. Note that entering more than 9 characters would have resulted in the program to be in fail state. This string was inserted into the cout stream by the write function on line 22 and exactly what we entered was printed. By the statement on line 23, we were prompted to enter a character array with a comma. We entered the string “ios,istream,ostream”. This string was extracted by the getline function on line 24. This getline function extracts a maximum of only 9 characters or until it encounters comma. In the string we entered, comma appeared as a fourth character. Therefore, it extracts only the first three characters, i.e., “ios” and it assigns them to the character array c. By Rule 5 of getline function, when a delimiter is encountered before extracting all the characters, a white space without a null character is appended to the extracted string. Note that, the character array c was already assigned with 8 characters and a null character was appended by the statement on line 21 and by the “Iostream” string we entered. After the getline function on line 24, however, the first three characters in
  • 8. By: Asaye Chemeda Email: asayechemeda@yahoo.com 53 c were replaced by the characters ‘i’, ’o’ and ‘s’ respectively and the fourth character was replaced by a white space appended to these characters. Which means that the first four characters extracted by the getline function on line 21 were replaced with the four characters extracted by the getline function on line 24. Since null character is not appended to the characters extracted by the getline function on line 24, the unreplaced characters in c still exist. Therefore, when c is printed by the write function on line 25, the displayed string is “ios ream”. By the way, we have solved the mystery why the getline function in the for-loop between lines 13 and 15 is not waiting for the same number as the value of len we enter. Can you give any suggestion how this could be improved? One of the ways to make the getline function inside the for-loop wait for the same number as the value of len is to extract the white space left in the input stream before the for-loop is entered. One of the ways to do this is to use the get function. For instance, including the following statement anywhere between the cin statement on line 10, where the white space is produced, and the first for-loop will solve the problem. Recall that we used the same approach in Program 3.8 in chapter three. On line 10 of program 3.8, we introduced the above statement to extract a white space left from an extraction operator. There are also other ways by which unwanted characters such as the white space produced by the extraction operator in Program 4.3, can be excluded from a string. The above option by using the get function only removes only one unwanted character at a time. In addition, it is not an ultimate way of removing unwanted characters from a string. C++ provides with another function by which any number of unwanted characters can be removed from an input stream. This function is the next topic to be discussed. The ignore function Another member of the istream class, ignore, discards specified number of characters or the characters before a delimiting character is encountered from the invoking stream. The function is overloaded to have the following two formal parameter types. In the syntax given by Form 1, the ignore function discards number characters from the istreamObject. The ignore function syntax given by Form 2 discards a maximum of number characters from the istreamObject if delimiter is not encountered. If a delimiter is encountered before discarding number characters, the discarding will be terminated after the delimiter is removed from the input stream. The default value for number is 1 and we can omit passing the value of number as an argument; in which case, the function assumes its value to be equal to 1. Let us consider the following piece of code. In the above piece of code, a character array c with a size of 100 is declared on Line 1. The statement on Line 2 makes the program wait until the user enters a character and discards 5 of them. If fewer than 5 characters are entered, the program still waits for an input. The ignore function also discards the newline character which is produced by pressing the ‘Enter’ key. After discarding 5 characters the program will proceed to executing the next line. The statement on Line 3 discards a maximum 10 characters or all the characters before the delimiter ‘,’ is encountered, whichever comes first, from the cin stream. If the delimiting character is not encountered nor 10 characters are not yet removed, the program waits for other characters to be entered. After 5 characters are discarded by the statement on Line 2 and 10 or the characters before ‘,’ are removed by the ignore function on Line 3, what is left in the cin stream will be extracted by the getline function on Line 4. If there is no any character in cin by then, the program will wait for other characters to be entered. By the way, the ignore function is the best candidate to solve the problem which we faced in Program 4.3, by discarding the unnecessary white space produced by the extraction operator. Since the default value for number of characters to be discarded is one, the following statement could also be used to discard the unnecessary white space. So far, we have learned a number of functions which are used to interact with the input and output streams. Didn’t
  • 9. By: Asaye Chemeda Email: asayechemeda@yahoo.com 54 they widen the options which we have to control what is passed to the program from the input stream and what is delivered to the output stream? Definitely yes. The functions which we learned are not the only ones and there are plenty. Are you interested in learning few more? I hope you are. Let us discuss the next ones then. Have you noticed that all the functions which we discussed so far always removed the characters which they handled from the input stream? What if we want to operate on a character without removing it from the input stream? What if we want to put back characters into the input stream? Does C++ answers for this question too? Of course, it does. The next topic will show us how. The putback and peek functions These functions are members of the istream class. Both functions can only handle one character at a time. The putback function puts back a character literal or the value of any character variable into the invoking input stream. Whereas the peek function returns the value of the first character in the invoking stream without removing the character from the stream. The syntax for the putback function is: The above statement puts characterVariable back into the istreamObject. The syntax for the peek function is: The above statement returns the value of the first character in the istreamObject and assigns its value to characterVariable. Let us consider the following code fragment. On Line 1, a character variable c1 is declared and initialized with what is going to be read by the cin.get(). The cin.get() on Line 1 makes the program wait for a character to be entered. When a character is entered, the get function on Line 1 removes it from the cin stream and assigns it to c1. This character, which is assigned to c1, is put back into the cin stream by the putback function invoked by cin as it is done on Line 2. After Line 2, the first character in the cin stream will be the character stored in c1. The peek statement on Line 3 reads the first character within the cin stream, which is the same as c1, and returns the value for a new character variable, c2. Note that the peek function doesn’t remove the character from cin. It just returns its value. The cin.get() on Line 4 then extracts the first character from cin and assigns it to a new character c3. The statement on Line 4 doesn’t make the program wait for a character to be entered. Because there is already a character in the input function. The character which is extracted from cin by the get function on Line 4 is the same character which was put back by the statement on Line 2 and which was copied by the peek function on line 3. Therefore, after Line 4, the value of the characters c1, c2 and c3 will be the same as the value which was entered on Line 1. Some of the functions which interact with the input stream may result in a program in fail state if inappropriate data is entered. For instance, if the extraction operator encounters a different data type than what it expects and if it can’t have other options to bypass the inappropriate data, the program will become in fail state. The getline function can also lead to a program in fail state if more characters than what it expects is introduced into the input stream. Do you remember what the consequences of a program in fail state are? All further input operations will be aborted and the output operations will display flawed results. In real world programs, however, entering inappropriate data may normally occur. For instance, in a software developed by C++ program, a user may enter inappropriate data. In such cases, the program would become in fail state. However, this is not how a good user interactive software is developed. The program should be capable to reverse any wrong data input into a normal working state. You may raise this question at this point: is it possible to resume a normal input operation after the program became in fail state? Of course it is. The next topic will show us how. The clear function Among the members of the istream class, the clear function, restores a program which is in fail state into a working state. However, to maintain a normal input and output process, the unnecessary data in the input stream should be cleared first after the clear function is invoked. This may be done using the ignore function. The syntax for using the clear function is:
  • 10. By: Asaye Chemeda Email: asayechemeda@yahoo.com 55 The clear function is best used with logical statements where a program continues with execution if appropriate data is entered or the program is cleared with clear function and the program is ready for another execution with another set of data. We have now covered what we need to discuss regarding the built-in functions which interact with the input and output streams. But, we haven’t seen a full program in which the latest functions which we discussed: ignore, putback, peek and clear were used. The program below uses all of these functions. Some of the procedures in the program are just introduced to show how the above function can be implemented in a program. There could also be other straight forward approaches. Anyways, let us have a look at it and discuss the basic points. Program 4.4[Correct].cpp The above program will be used to prompt a user enter five names along with their scores, store these user inputs and display the names and the corresponding scores. In the program, a character variable c, a boolean variable isFailState, a float array score and a two- dimensional character array name were declared from line 4 up to line 7 of the program. The variable isFailState is initialized with false and the number of rows of score and name are defined to be 5. Two for-loops are used in the program. One to for the input part another for displaying the names and scores. The first for-loop extends from line 8 up to line 30 whereas the second for-loop is between lines 32 and 38. The body of the first for-loop starts by prompting the user to enter a name. Then, there is a do-while loop between lines 10 and 12. This loop is intended to discard any white spaces before the entered name. It could also be done within a single line by using the ignore function. The reason why the loop is introduced is to show how the putback function is used. In this do-while loop between lines 10 and 12, a character is extracted from cin and assigned to the variable c by using get function. The loop continues while the character stored in c is equal to the white space character. As soon as the variable c gets non-white space character, i.e., after all the white spaces are discarded, the loop will be exited. However, the last loop extracts and assigns the first non-white space character to c. This character is part of the name entered by the user. Therefore, it should be put back into the input stream. The statement on line 13 performs this task using the putback function. Then, the rest characters will be extracted by the getline function on line 14 and will be assigned to the ith row of name array, i.e., name[i]. On line 15, the user is prompted to enter the score for the entered name. Note that, if the user enters a data which doesn’t correspond to float data type, the program will become in fail state. If so, any further input operations will be aborted. Don’t you think this makes the user irritated? Suppose you are using a software and you entered a wrong data by mistake and the program stops working as a result of that. Don’t you get frustrated by the software? You might be. Therefore, if you are a programmer writing a code for a software and if you want your software to be competitive, you should foresee such issues. Then, what could be done in this particular program to avoid a program in fail state? We can use the clear function, right? But how do we know whether a wrong data was entered or not? We should check whether the data is entered correctly or not while the data is inside the input stream. Are there facilities in C++ to achieve this goal? Of course there are. We can use the peek function, right? That is what the if-statement on lines 16 and 17 will do. It checks what kind of data is in the cin stream without removing the data. Note that the return value of the peek function is the ASCII value of the character.
  • 11. By: Asaye Chemeda Email: asayechemeda@yahoo.com 56 If the first character in the input stream is a floating point number, its value should be between 1 and 9 (excluding scores which are less than 1). The peek function will now be used to check whether the character in the cin stream is a whole number between 1 and 9. The ASCII numbers of the characters 1 up to 9 is 49 up to 57 in their respective order. Therefore, after the user entered a value corresponding to score and if the first character in the input stream is a character with ASCII value outside the above range, it will lead to a program in fail state. In these cases, we need a flag within the program to indicate that the program is going to be in fail state. Like the flag in football games which will be raised when a ball crosses the boundary lines. In program 4.4, the flag is the isFailState boolean variable. After the user is prompted to enter the score and if the ASCII value of the first character entered by the user is less than or equal to 48 or greater than 57, the value of isFailState becomes true, otherwise its value will remain to be false. In short, the if-statement on line 16 changes the value of isFailState to true when the first character in the cin stream is not a number between 1 and 9. On line 18, the extraction operator is used to extract the input for the ith row of score. Note that, if wrong data is entered, this statement will lead the program to be in fail state. If so, however, the if-statement on line 16 would have already foreseen this and would have changed the value of the isFailState variable to true. If the value of isFailState is true, another if-statement extending from line 19 to line 28 executes the clearing and brings the program into a working condition. When the statement on line 18 makes the program to be in fail state, the statements within the body of the second if-statement will be executed. In this if-statement, the program will be restored into a working condition by the statement on line 20 using the clear function. Then the ignore function used on line 21 discards the unnecessary characters in the cin stream. After this, the user is prompted to enter a correct score. Note that, at this time too, the user may enter inappropriate data. Therefore, a while loop is used to loop until the user enters a correct value for a float data type variable. The truth statement for the while loop is the same as that of the if-statement on line 16. Within the while loop, the unnecessary characters in the cin stream will be discarded each time the user enters a wrong data. Actually, this could also have been done on line 16 itself instead of the if-statement and we could have avoided a few statements within the program. However, if statement is used on line 16 to show how the clear function works. The cin statement on line 27, extracts a value for the ith row of score array once the program entered into a fail state. The statement on line 29, discards one unwanted character. Can you guess what that unwanted character could be? It is the white space produced by the extraction operator on line 18 or the one on line 29. On line 30, the value of isFailState is assigned with a value of false. Otherwise, the program enters the if-statement on line 19 on the next loop even if the user enters correct data. The content of the second for-loop between lines 32 and 38 is straight forward. The statement to note may be the while loop on line 34. This while loop is used to count the number of characters in each row of the name array before the null character. The number of characters is determined by incrementing the value of an int variable j until the null character is encountered. When the while loop is exited, the value of j will contain the number of characters for the ith row of the name array. Then this is used to insert the exact number of characters into the cout stream by using the write function. A cout statement is used on line 36 to display the corresponding score for each name. The above program may require further enhancements to avoid all possible runtime problems. However, we have used it satisfactorily in order to see how some of the built- in functions in the istream and ostream classes are used in a program. Let us now have a closer look at how the output stream works. When data is fed to the output stream, it will not send all the data to the output device immediately. It keeps on storing the data in a buffer until the stream is full. Sending the data to the output device only starts after the stream is full. Now, consider there is a power outage after a data is inserted by a program to the output stream and before the output stream becomes full. What do you think will happen? The output device will not display the data which the program is supposed to do. Because the data was still in the output stream waiting for the output stream to be full and to start being displayed on the output device. But, is there any way in C++ by which we can force data in an output stream to be flushed to the output device? Of course there is. The next topic will discuss how this is done. The flush function The member of ostream class, flush, forces any data within the output stream to be sent to the output device without waiting for the stream to be full. The syntax to use the flush function is:
  • 12. By: Asaye Chemeda Email: asayechemeda@yahoo.com 57 If the flush function is invoked as in the above statement, any data within ostreamObject will be flushed to the output device automatically. The concepts which we discussed so far deal basically with how the input and output streams work and how different functions interact with these streams. The majority of the built-in functions which we discussed mainly deal with extraction or insertion of data from or to streams. None of them were used to deal with arranging the data in a formatted manner. However, some real world programming applications may require the outputs to be displayed in specific formats. For instance, a programming application which calculates the total price of goods may need to be programmed to send a value in exactly two decimal places to the printing device. Some of the functions which we discussed previous may be combined to have such formatted output. But, those approaches would require more lines of coding. In programming, achieving the desired programming goal with the fewest number of statements is usually preferable. Because, the more the number of statements, the more vulnerable the program will become for errors. In addition, fewer lines of coding make a program to be neater. As a result, instead of using the functions in the istream and ostream classes to have a formatted input or output data, the other set of built-in C++ functions can be used. The outputs through put and write functions are unformatted outputs and cannot be made to have a specific formatting style. Formatting of outputs in C++ is usually done by using the built-in functions in the iostream file or in the iomanip file. The ios class in the iostream file has a number of functions which are used to arrange an output in a desired way. A similar formatting can also be done by the so called manipulator functions in the iomanip file. However, the formatting functions in both files have their own limitations and capabilities. Based on these limitations and capabilities, the functions which can achieve a desired formatting style for an output from either of the files can be selected at the programmer’s discretion. Formatting output using the ios class functions The ios class in the iostream file has a number of functions which can be used to have a specific format for an output. Some of the functions in this class are listed below. width – allocates a specified number of character spaces for an output. precision – puts the output in specified number of decimal places. fill – fills empty spaces of the allocated character spaces for an output with designated character. setf – sets a specific flag for an output. unsetf – reverses the flag set by setf function. flags – returns the current formatting style or sets formatting style contained by a variable. All of the above functions are invoked by an output stream (ostream class object) by using the member access operator. Now, let us see how the above functions can be used in a program. The width function The syntax used for width function is: The above statement allocates number character spaces for the very next output operation to the ostreamObject stream. If the number of output characters to be displayed is greater than number, all the output characters will be displayed outside the boundary allocated by the width function. Let us consider the following piece of code: In the above piece of code two float variables x and y are declared on Line 1. The variable x is initialized with a number which has two digits before the decimal place and three digits (including the trailing zero) after the decimal place. Whereas the variable y is initialized with a number which has one digit before the decimal place and two digits after the decimal place. Note that the variable x has six characters including the decimal point and the variable y has four characters. On Line 2, ten character spaces are allocated for the next output operation using the width function. Therefore, the very next output operation will be accommodated on the right side of these 10 character spaces. The output will be accommodated on the right side because by default an output is displayed right-justified. On Line 3, the values of x and y are inserted into the cout stream using the insertion operators. Since the first output operation after the formatting on Line 2 is the insertion of the value of the variable x into cout stream, the value characters in the value of variable x will be accommodated on the right side of the 10 character spaces allocated by the width function on Line 2. Note that the value of the variable x has six characters including
  • 13. By: Asaye Chemeda Email: asayechemeda@yahoo.com 58 the trailing zero. However, trailing zeroes are not displayed in the output unless the format setting is changed to do so. Therefore, only five of the six characters (including the decimal point) without the trailing zero will be accommodated within the 10 character spaces. Therefore, the displayed output by the statement on Line 3 appears to be: In the above output, it can be observed that the value of the variable y is displayed next to that of x without being formatted. However, the trailing zero in the variable x is omitted in the displayed output. Since x has five characters to be displayed and ten character spaces were allocated for it, there are five unoccupied character spaces. To understand a little bit more about how the width function operates, let us consider the following piece of code. The output of the above piece of code will look like: Even if the width is set to 3 on Line 2 for displaying value of x which has five displayable characters, all the five characters were displayed. Therefore, if the number of displayable characters in an output is greater than the width set by the width function, the later will be overruled. On Line 4, another setting for width of an output is set. In this case, 10 character spaces were allocated for the next insertion operation which is displaying the value of square root of 3. Note that square root of 3 is an irrational number and it has infinite number of digits. But, the number of displayed digits after decimal places for most compilers is six. Therefore, six digits will be displayed after the decimal place if there are no trailing zeroes and if the setting for default number of decimal places is not changed. The value of square root of 3 up to six decimal places is 1.732051. Which means that there will be 8 displayable characters. However, 10 characters spaces are allocated. Which means that there will be two unoccupied spaces. Note that when the width function allocates character spaces, the counting for the allocated spaces starts from the very last character in the output stream unless a newline character is introduced. When character spaces are allocated for an output using the width function, the number of digits after decimal places are fixed unless the setting is changed to display more number of digits. But, some numbers, such as the value of π, may contain more than the default value of number of digits and it may be required to display all the digits. In those cases, another function of the ios class can be used. This function will be the next topic to be discussed. The precision function The syntax used for precision function is: The above statement sets number digits to be displayed after the decimal place when an output is displayed from ostreamObject until the setting is changed. The function can also be called without passing an argument. In that case, it returns the current precision setting of the program. The precision function will not force trailing zeroes to be displayed. The use of the precision function is shown in the following piece of code. The statement on Line 1 prints the current precision setting by using the precision function with empty parameters. If the precision has not been set before, this statement will display a value of six for most compilers. The statement on Line 2 indirectly prints the value of π which is also equal to two times sine inverse of 1 in radian units. This line prints the output as below and there are six digits after the decimal point. On Line 3, the precision setting is changed to ten digits after the decimal point. The statement on Line 4 displays the precision setting after it was changed on Line 3. This will display a value of 10. The statement on Line 5 again prints the value of π after the setting is changed. The displayed output will be: Now, the printed number of digits after the decimal point has become 10 as it was set by the statement on Line 3.
  • 14. By: Asaye Chemeda Email: asayechemeda@yahoo.com 59 Based on our discussion, can you answer what will be displayed by the statement on Line 3 of the following piece of code? Did you answer as 39.700? Or did you recall that the precision function will not force trailing zeroes to be displayed even if the precision setting includes them? The cout statement on Line 3 prints only 39.7 omitting the trailing zeroes. The width function allocates six character spaces put the four displayable characters on the right hand side as follows. When the number of characters in an output are less than the space allocated by width function, there will be empty character spaces in the displayed output. However, some programming applications may require to avoid such unoccupied character spaces when the output is printed. For instance, unoccupied character spaces in bank checks may need to be avoided to prevent any addition of extra digits in the unoccupied character spaces. As a result, the empty character spaces may need to be avoided. At the same time, a program application may need to set the width with small as well as large number of characters so that outputs with wide range of characters will be accommodated. Then, when outputs with small number of characters are printed, there will be unoccupied characters spaces. In such cases, we can use another function from the ios class. This function will be discussed next. The fill function The syntax used for fill function is: The above statement fills unoccupied character spaces with character for the coming output operations to the ostreamObject stream. The value character can be a character literal or a character variable. The format setting by fill function persists until the setting is changed. To see how the fill function operates, the following code fragment will be considered. In the first line of the above code, the double variable amount is declared and initialized with a number having five characters (including the decimal point). On Line 2, the width for the next insertion operation is set to 10. The statement on Line 3 fills any unoccupied spaces with the ‘*’ character by using the fill function. The value of amount is inserted to cout stream as the first insertion operation on Line 3. Since amount has only five characters and since 10 character spaces are allocated, it is expected that five of the spaces will be filled with the ‘*’ character. The value of amount will be displayed as follows: The unoccupied five spaces are now filled with the character which is used as an argument when the fill function is invoked. Note that the filling by fill function takes place wherever there is an empty space; whether it is in front of or inside or after the displayed output value. By the way, we do not have to take output formatting as a luxury topic. Some programming applications may require strict output styles. Therefore, detailed understanding about the formatting facilities in C++ might be vital. We have already discussed how some formatting styles can be achieved. Besides, we have also noted some formatting styles which couldn’t be handled by the functions which we discussed so far. For instance, none of the formatting functions which we discussed couldn’t enforce the displaying of trailing zeroes. The functions couldn’t also change the justification of the output. However, this doesn’t mean that C++ doesn’t have the facilities to handle those styles at all. Other styles which were not achieved by the previous ios class functions can be easily handle by setting different flags. In C++, flags are Boolean variables which signify that a certain state is reached within the program. For instance, a state may be reached when right-justified output setting is just to be changed to left-justified output setting. In such cases, we need flags to indicate that a particular state is being reached. There are a number of flags for different programming states. These flags can be set and unset thereby achieving some desired output style. How this is done will be the next topic to be discussed. The setf , unsetf and flag functions The setf function is an overloaded function and may have one of the following two forms: The syntax given in Form 1 takes one argument. By this statement flag is set for the outputs through ostreamObject and the flag will persist until it is
  • 15. By: Asaye Chemeda Email: asayechemeda@yahoo.com 60 unset. As part of the argument the function name where the flag belongs (ios) and the scope resolution operator (::) should always precede the flag. The syntax given in Form 2 takes two arguments. By this statement previous settings corresponding to flag2 will be cleared first and flag1 will be set as a flag for the coming output operations into ostreamObject and the flag given by flag1 will persist until it is unset. Both arguments should be preceded by the function name where the flag belongs (ios) and the scope resolution operator (::). A number of flags can also be combined as a single setf function argument using the OR operator. This avoids writing multiple lines which could be written to change the setting for each flag. The syntax for such setf function with combined flags when invoked by the cout stream is given below. The frequently used flags in ios class are: left – makes the output left-justified. right – makes the output right-justified. showpoint – enforces displaying of trailing zeroes. showpos – displays the + sign when positive numbers are displayed. fixed – puts the output in fixed number notation. scientific – puts a floating-point output in scientific notation. boolalpha – allows input and output of Boolean values by using the keywords true and false. dec – displays an output as decimal (base 10) number. oct – displays an integer output as octal (base 12) number. hex – displays an integer output as hexadecimal (base 16) number. The following flag groups consist of more than one flag and can only be used as a second argument in the setf function which takes two arguments. adjustfield – refers to the left and right flags. floatfield – refers to the fixed and scientific flags. basefield – refers to the dec, oct and hex flags. The frequently used flags which can be set to display an output in different styles are given above along with explanations what the specific effect of each flag is. Instead of looking into pieces of codes to discuss how each of the flags affect an output setting, let us write a program and analyze the displayed outputs. For this, let us consider the following program first and the resulting output. Program 4.5[Correct].cpp The output for the above program is shown below. Since the only formatting functions used in the above program are width and fill and since the effect of these functions was discussed in detail, no further discussion will be made on the output. Now, let us introduce the left, showpoint and showpos flags in the program and analyze the output. A Boolean variable isPrintComplete was also declared and initialized with a value of false. This variable attains a truth value of true after all the desired output are printed. Program 4.6[Correct].cpp
  • 16. By: Asaye Chemeda Email: asayechemeda@yahoo.com 61 In the program, the statement on line 9 clears all ajustfield flags and sets the left flag to be the used as a justification flag for the outputs. By default, C++ outputs are right-justified, i.e., they are written on the right hand side of the allocated space. As can be seen from output of program 4.5, all the outputs are printed on the right hand side of the allocated space. However setting the left flag puts them on the left hand side of the allocated spaces and the unoccupied spaces will be shifted to the right side. Which means that characters used as an argument of fill function will be on the right hand side. On line 10, the showpoint and showpos flags were combined using the OR operator and passed as an argument to setf function. Therefore, after this line trailing zeroes will be displayed and the + sign will be shown for positive values. On line 23, the value of isPrintComplete is changed to true. On line 24, the value this Boolean variable is printed. Normally, C++ programs consider Boolean variables to be 1 for true and 0 for false. Since the value of isPrintComplete at the time of its printing is true, the cout statement displays 1 and the showpos flag set on line 10 adds a + sign before the value. If it is desired to print the value of isPrintComplete as ‘true’ or ‘false’, the boolalpha flag should be set. The output for program 4.6 is shown below. The outputs are left-justified, the empty spaces on the right hand side are filled, the + sign is added and the trailing zeroes are displayed. Let us consider again the Program 4.6 where the left, showpoint and showpos flags are substituted by hex and scientific flags. Since the hex and oct flags operate only on int data types, two arrays, one with int data type and another with float data type, were declared. On the other side, the scientific flag operates only on floating-point data types. Program 4.7[Correct].cpp On line 8 of the program, all the flags corresponding to basefield are cleared first and the hex flag is set. Therefore, integer values will be displayed in hexadecimal numbers. On line 9, the scientific flag is set. Note that, the floatfield flag group could also be used as a second argument on line 9. However, mentioning the second argument is mandatory only when it is desired to clear all the previous settings for the flags corresponding to the group. The outputs will now be displayed in three columns. The second column displaying the output of an int data type price array whereas the third column displays the output for float data type price2 array. The boolalpha flag is now set on line 27 and the output of the isPrintComplete variable on line 28 will be the keyword true. The output of program 4.7 is shown below. In the output, characters are right-justified, empty spaces are filled, int data type values are displayed in hexadecimal numbers and floating-point values are displayed in scientific notation. Once a flag is set, the setting can be reversed by using unsetf function when the flag is no longer required or
  • 17. By: Asaye Chemeda Email: asayechemeda@yahoo.com 62 to return to the default setting for that particular flag. The syntax used for the unsetf function is the same as that of setf function. The only difference is the unsetf function is not overloaded to take two arguments. The following statement reverses flag setting to the default setting for outputs through ostreamObject. For instance, the following statement clears the left-justify setting and returns the justification setting to the default setting. The unsetf function also takes flags combined with OR operator as an argument. In which case, all the flags combined by the OR operator will be set to their default setting. The following statement clears the showpoint and showpos flags. We have seen that by setting and unsetting different flags, we can display outputs in different formatting styles. Now, let us see the strong side of the functions in ios class which cannot be attained by the formatting functions in the iomanip file. The main advantage of the flags in the ios class is that they can be assigned to a variable with fmtflags data type. Consequently, any particular flag setting which is assigned to a variable can be used to set a flag anywhere in the program by using the variable. Combined flags can also be assigned to variable. The syntax to create a flag variable is: In the above declaration, a combination of flag1, flag2 … flagN is assigned to variable f which is of a fmtflags data type. Once a flag variable is declared, it can be used at another place of the program. For this, the flags function can be used. The flags function is overloaded and it has one of the following two forms: The syntax given in Form 1 returns the current flag setting of ostreamObject. Therefore, it can be assigned to variable with fmtflags data type. The syntax given in Form 2 sets the flag for outputs through ostreamObject to flagVariable. The following program shows how flag variables and the flags function can be used. Program 4.8[Correct].cpp In the above program, the statement cout.flags() on line 4 returns the current flag setting of the program and assigns it to f1 variable. Since no flag was set in the program before the statement on line 4, f1 will contain the default flag setting. On line 5, another flag variable f2 was declared. This flag variable will contain the combined showpoint, showpos and left flags. On line 7, a minimum width of 10 is set for the output on line 8. Note that, until line 8, the flag setting is the default flag setting used by the compiler. Therefore, when the value of 100.10 is printed by the cout statement on line 8, it will be right-justified, and trailing zeroes will be omitted. On line 9, the flag setting is altered by using the flags function to the flag settings contained by the f2 variable. Again, the minimum width is set to 10 by using width function on line 10. As a result, when the value of 100.10 will be displayed by the cout statement on line 11, it will be left-justified, trailing zeroes and the + sign will be displayed. On line 12, the f2 flag setting is cleared by using unsetf function. Which means that when the value of 100.10 is printed, the default flag setting will be used. The output of the above program will look like: Controlling how the output is displayed through ios class functions was exciting, right? Of course it was.
  • 18. By: Asaye Chemeda Email: asayechemeda@yahoo.com 63 Besides, the formatting procedures are very applicable for real world programming too. The ios class functions have their strengths in being assigned to a flag variable. Despite this, they have some shortcomings as well. The main limitation of the ios class formatting functions is that they have to be always written as a separate statement; each statement requiring the output stream to invoke the function. Which means that they cannot be embedded within insertion operators where one output stream invokes a number of functions. As a result, several lines of coding is required making the program to be error prone. Don’t you think it is better if the functions could be embedded within the insertion operators? Wouldn’t this avoid several repetitions of separate invocations the functions by the output stream? The ios class functions would definitely be more versatile if they could be embedded within the insertion operators. But, they already have their strong sides. Their limitation is possessed while their strong side is lost by the so called manipulator functions in the iomanip file. Are you ready to learn the functions in this file? As most of this functions have an equivalent from the ios class, understanding how the manipulator functions will be used is very easy. Formatting output using the manipulator functions The iomanip file has a number of functions which can be used change the formatting styles of an output. In order to use these functions within a program the iomanip file should be included in the program. Some of the functions in this file along with the equivalent ios class functions are listed below. setw – allocates a specified number of character spaces for an output. [Equivalent with width] setprecision – puts the output in specified number of decimal places. [Equivalent with precision] setfill – fills empty spaces of the allocated character spaces for an output with designated character. [Equivalent with fill] setiosflags – sets a specific flag for an output. [Equivalent with setf] resetiosflags – reverses the flag set by setf function. [Equivalent with unsetf] endl – displays the next output on a new line. All of the above functions are invoked by an output stream (ostream class object) by using the insertion operator. The way how the above functions are used in a program is the same as the way how the equivalent functions in the ios class are used. A significant difference is the manipulator functions cannot be assigned to a variable but the ios class functions can. In addition, the manipulator functions can be concatenated by using the insertion operator on a single output stream whereas the ios class functions can’t. Therefore, no further separate discussion will be made for each of the functions. However, mentioning the flags in the iomanip file is vital and the most frequently used ones are listed below. left – makes the output left-justified. right – makes the output right-justified. showpoint – enforces displaying of trailing zeroes. noshowpoint – turns off the showpoint flag. showpos – displays the + sign when positive numbers are displayed. noshowpos – turns off the showpos flag. fixed – puts the output in fixed number notation. scientific – puts a floating-point output in scientific notation. boolalpha – allows input and output of Boolean values by using the keywords true and false. noboolalpha – turns off the boolalpha flag. dec – displays an output as decimal (base 10) number. oct – displays an integer output as octal (base 12) number. hex – displays an integer output as hexadecimal (base 16) number. To see the equivalency between the manipulator functions and the ios class functions, we will format the output for Program 4.7 using manipulator functions. When the output of Program 4.7 is entirely formatted by the manipulator functions, the program will appear to be as follows. Note that the iomanip file is included in the program. Program 4.9[Correct].cpp By the statement on lines 9 and 10 of program 4.9, the flags in basefield are turned off and the hex and scientific flags are turned on. Notice how the resetiosflags and the setiosflags are
  • 19. By: Asaye Chemeda Email: asayechemeda@yahoo.com 64 concatenated using the insertion operator on a single cout stream. In program 4.7, this was done by separate statements. The statements from line 10 up to line 15 of program 4.7 are combined by a single statement on line 11 of the program resulting in the same effect on the output. Note how the setw function replaced the width function for the same arguments. Inside the for-loop, the statements from line 17 through line 24 of program 4.7 are replaced by a single statement on line 14 of program 4.9. The setfill function inside the for-loop of program 4.9 replaced the fill function in program 4.7. The two statements which were used to set the boolalpha flag and display a Boolean variable in program 4.7 are now reduced to a single statement line 18 of the program. Note that the output of program 4.9 is displayed in exact the same setting as that of program 4.7. However, the possibility for concatenation of the manipulator functions allowed to have fewer statements in program 4.9. This shows the edge that the manipulator function have over the ios class functions in having fewer number of statements and therefore less error prone program. However, if we refer program 4.8 and notice how the functions in ios class can be assigned to a variable, we understand that the ios class functions have an edge over the manipulator function as well. This disadvantage of the manipulator functions, however, can be improved by defining sequence of manipulators. The syntax to create such customized sequence of manipulators for an output stream is: The above syntax is just like defining a function which returns and receives by reference in which ostream is the return type of the function and the data type of the parameter, name is the function name and variable is the argument. The name and variable can be any qualified identifiers. On the last line of the definition of the sequence of manipulators, variable should be returned. Within the body, any output formatting operations by either the manipulator functions or the ios class functions can be included considering variable as an output stream. Once the sequence of manipulators are created as above, name can be used within extraction operators to enforce the format settings included in the body of the definition. Creating sequence of manipulators is helpful where the same sequence of formatting operations are frequently used in a program. This avoids repetitions of codes making the program neater as well as less error prone. The output setting achieved in Program 4.8 by assigning flags to flag variables can exactly be replicated with the following program. Program 4.10[Correct].cpp In the above program, two sequences of manipulators customSetting and defaultSetting were defined. The customSetting has the same setting as flag variable f2 of program 4.8 with the exception that customSetting allocates 10 character spaces for the output. The customSetting turns on the showpoint, showpos and left flags whereas the defaultSetting does the opposite but it also allocates 10 character spaces for the output. The main function extends from line 18 to line 23 of the program. On line 19, the value 100.10 is printed by first invoking the defaultSetting sequence. The task of this statement is just like printing the value with the default compiler format setting except that the width is set to 10. On line 20, the value 100.10 is printed by first invoking the customSetting sequence. Since the format setting in customSetting combines the statements on line 9 and 10 of program 4.8, calling the sequence will have the same effect on the output as the mentioned lines of program 4.8. On line 21, the value 100.10 is printed by invoking the defaultSetting sequence first. This will have the same effect as lines 12 through line 14 of program 4.8. Note that within the defaultSetting and customSetting sequences, ios class functions could also be included. However, the above program was
  • 20. By: Asaye Chemeda Email: asayechemeda@yahoo.com 65 intended to show how the shortcoming of the manipulator functions can be improved by creating sequence of manipulators. As a result, only manipulator functions were used in the sequences. Through the ios class and manipulator functions, we have seen how outputs can be formatted using different styles. Wasn’t it interesting? Indeed it was. But, they are not the only functions used in C++ to format outputs. C++ program has adopted another function from C to format outputs with wide range of data types. This function is versatile and discussing its application is very useful. The printf function One of the derived functions from C program, printf, can be used to print a formatted output to the console. This function is best used when printing combination of different output data with different format settings at once is required. The function is overloaded to receive different number and data types of arguments. In order to use the function, the stdio.h file should be included in the program. The general syntax to use the printf function in a program is: In the above syntax, the formatSpecifier basically contains one or more format specifiers along with other characters. Each format specifier contains the percent sign (%) followed by format code. The format code depends on the data type which is going to be printed by the function. Among many format codes, c stands for characters, d for signed integers, f for floating point values, s for strings, p for pointers, e for scientific notation and x for hexadecimal numbers. The rest arguments, variables, will contain the same number of variables as the number of format specifiers. The variables should be separated by a comma and placed in the same order as the order of the format specifiers placed within the first argument. The following statement prints 1m on the screen. The first argument in the above statement contains two format specifiers, %d and %c. Therefore, two other arguments matching these format specifiers. Since the format code d stands for integers, the first argument after the format specifier should be an integer. The other argument should be a character as the format code c stands for characters. Other characters than the format specifiers can also be included in the first argument of printf function. Let us consider the following statement. In the above statement, there are two format specifiers in the first argument, %d and %s. The inclusion of additional characters in the first argument is also legal. When the output is displayed on the screen, the arguments outside the double quotes will replace the places occupied by the format specifiers. However, the arguments outside the double quotes should be placed in the same order as they are put in the first argument. An integer first and a string next. The above statement displays the following on the output. As can be seen from the output, the second argument, 3, replaced the %d specifier in the first argument and the last argument, “C++” replaced the %s specifier. The format setting for some data types can also be adjusted by introducing numbers between the % sign and the format code. These numbers can be a single integer or two integers separated by a dot. The effect that putting numbers between the % sign and the format code depends on the data type. The number 0 can also precede the first integer. The number between the % sign and the format code is generally put as 0x.y, where x and y are integers. The preceding 0 is used to fill empty character spaces with 0. The value of x represents the minimum allocated character spaces for any data type. The meaning of y is different for different data types. For integers, it represents the minimum number of digits. If the integer contains less digits that y, the 0 characters will precede the number. For floating point data types, it represents the number of digits after decimal places. For strings, it represents the maximum number of characters. The following statement displays the number 1298.567 with 9 character spaces and 2 digits after the decimal point and fills any empty spaces with 0. The output of the above statement is: The following statement displays the number 1000 after the string “Output” with 10 character spaces and 5 digits within the allocated character spaces.
  • 21. By: Asaye Chemeda Email: asayechemeda@yahoo.com 66 The output for the above statement looks like: When an output is displayed using the printf function, it is right-justified. In order to display the output left- justified, we need to put minus (-) sign just after the % sign. The following statement allocates a minimum of 15 character spaces and prints a maximum of 10 left- justified characters from the “Programming” string. The output of the above statement is shown below: The above output is left-justified. Only 10 of the 11 characters in the string are printed in the 15 allocated character spaces. The printf function is very helpful in order to concatenate a string message with variables of different data types with a specified format setting. It avoids invoking a number of formatting functions in the ios class or iomanip file. For instance the following program has a closer effect on the printing of price and price2 arrays given in program 4.9. Program 4.11[Correct].cpp The statement on line 8 of the above program avoids the multiple invocations of the setw function on line 11 of program 4.9. Although filling the empty spaces with designated characters could not be replicated, the statement on line 11 of the program 4.11 again avoids the multiple invocations of the setw function used on line 14 of program 4.9. The statement on line 14 of program 4.11 shows that how the printf function easily integrates a string message with a variable used in the program. This statement displays the number of items printed by using the last value of the counter used in the for-loop. When the above program is run, the displayed output is: Isn’t the printf function efficient in formatting outputs? Of course it is. The way how the function integrates a string message with other variables of different data types is also superior to the functions in iostream file or iomanip file. However, it has a severe limitation. In contrast to the iostream file or manipulator functions, which can display outputs to wide variety of output devices, the printf function can only display an output to an internal displaying device, which is usually the screen. Speaking of, we haven’t yet discussed about input and output operations beyond the default input device (keyboard) and output device (screen), right? However, at the beginning, we have said that the input and output streams in C++ can interact with any type of input or output device. Among the many input or output devices, however, using files as an input source or an output destinations is frequent task which a programmer often encounters. Therefore, it is worth discussing about how input and output operations on files is done separately. The next topic discusses this concept in detail. File Input and Output (I/O) Using files as an input source and an output destination might sometimes become preferable to input and operations on standard input and output devices. If an input data involves several characters, using the keyboard to enter the bulky data every time the program runs might become tedious. In those cases, the input data may be stored in files and the program can be made extract the input from the file. This avoids the tedious typing process and the accidental errors which may occur in doing so. Displaying the output to the screen has also certain limitations. First, the screen accommodates limited number of characters for display. Therefore, when there is a large data to display, the screen is unusable and using files becomes very handy. Second, the outputs made on the screen cannot be saved and cannot be used at a later time or as an input for other applications. Due to the above limitations of I/O operations on standard devices, files are often used to read input from and write an output to. Input and output operation on files are much similar to those on standard devices. There are notable distinctions though.
  • 22. By: Asaye Chemeda Email: asayechemeda@yahoo.com 67 The input and output streams for I/O operations on standard devices are created as soon as the program starts execution. As a result, manual creation of the input and output streams is not necessary. On the other hand, the input and output streams to read data from or write to files should be created manually within the program. Creating these streams is not that difficult though. Besides creating streams, another notable distinction between the I/O operation on standard devices and files is that both the input and output streams for file I/O should be associated with the files which they operate on. Otherwise, I/O operations on files and on standard devices are much alike. In addition, most of the functions which are used to integrate the streams with the program for standard devices can be used for files as well. As the iostream file handles the input and output streams for I/O operations on standard devices, the fstream file handles the input and output streams for file I/O. Therefore, whenever file I/O operation exists in a program, the fstream file should be included in the program. Typical file I/O operation involves the following four steps: 1. Creation of a stream 2. Association of a file with the stream 3. Operation on the file 4. Dissociation of the file with the stream. Each of these steps will be discussed one by one. In an object-oriented approach, the first and the second steps can be combined. Since this approach is not that complicated either, it will also be included in our discussions. Creation of a stream Three types of streams can be created for file I/O. An input stream for input operations, an output stream for output operations and an input/output stream for both input and output stream operations. Each type of the streams is created by declaring a variable with the data type of the class corresponding to the stream. The class corresponding to the input stream is ifstream. Whereas, the class corresponding to the output stream is ofstream. The fstream class corresponds to input/output stream. Once a variable is declared with a data type of these classes, it will be used as a stream like the standard streams such as cin and cout. The name of the variable can be any qualified identifier. The syntax to create an input, output and input/output streams is: After the above declarations, inputStream will be used as an input stream like cin to read data from files. The outputStream can be used as an output stream like cout to write data to files. The ioStream can be used as both input and output stream to read from and write to files. The important property of file input and output streams is that they can only interact with only one file at a time. If the program requires to interact with more than one file for either the input or the output stream at the same time, the same number streams should be created and each of them should be associated with a single file at a time. But, an input or output stream can be used to interact with another file after being dissociated with the first file. Association of a file with a stream Another important step in file I/O is associating each stream with the file with which it interacts with. The input stream should be associated with the file from which data is read. The output stream should be associated with the file to which a data will be written. This can be done in one of the two approaches available in C++. The first one is by using the open() function. The second approach is including the file name during the stream itself. The syntax for both approaches is shown below. The above approach uses the open() function to associate the file which has fileName with the corresponding stream. The above approach simultaneously creates streams and associates them with the file which has fileName. If the file is not in the same directory as the directory which the program points to, the full path should be mentioned with fileName. If a file with a specified file name is not available in the directory, the input stream leads to a program in fail state while the output stream creates a new. Therefore, including a code which checks the availability of the file with the specified file name in the program is important to avoid a possible input stream failure. When an output stream interacts with an existing file as shown above, it first erases all the data in the file.
  • 23. By: Asaye Chemeda Email: asayechemeda@yahoo.com 68 Operation on the file Once a file is associated with a stream, any valid operation can be performed on the data extracted from the file. The output results can be send to a file. Suitable formatting styles can also be applied to the output. For this, the functions in the iostream class or fstream class can be used. In general, after associating a file to a stream, the normal C++ procedures can be applied with the data extracted to the program as an input and to the data sent to the destination as an output. The functions which are peculiar to file I/O will be discussed briefly while the functions which are used for I/O operation on standard devices will be reviewed. Dissociation of a file from the stream After the necessary I/O operation is performed on files, they should be dissociated from the stream. This may have several advantages. First, the stream which is dissociated from a file can be used for another I/O. Second, the dissociation flushes any remaining data in the stream and the file can be used for further activities. The dissociation of files from a stream is done by using the close() function. This function doesn’t take any arguments. It is invoked by the stream for which the dissociation is going to be done with the member access operator. The syntax to dissociate a file from an input, output and input/output streams is: We have covered the basic steps in file I/O. It was fascinating! Wasn’t it? File I/O is as interesting as I/O operation to standard devices. Now, let us discuss the functions which are often used in file I/O. The open function We have seen that the open function is used to associate a file with the stream. Here, we will discuss the features of the function which were not discussed before. After an input stream invokes open function, the stream may evaluate true in Boolean expressions if the file which is passed as an argument exists and EOF is not reached in the file or false otherwise. Thus, the input stream can be used in a code that checks whether the file exists or not so that further actions can be taken depending on the outcome. At the same time, the input stream returns true when the EOF is not reached or false otherwise. This concept can be used as a logical expressions so as to limit the input stream from trying to extract data beyond EOF. The open function actually takes two arguments. The first argument is always the file name. Whereas, the second argument is a parameter which describes the mode how the file will be opened. In the function definition, the second argument is initialized in the formal parameter list. As a result, passing the second argument is optional. A number of alternatives are available for the mode. These alternatives are listed as follows along with their explanation. ios::in – specifies that a file is capable of input. ios::out – specifies that a file is capable of output. ios::app – appends an output to the existing data in the file. It is used for output capable of output only. ios::ate – points to the end of file (EOF) when the file is opened. ios::binary – opens the file in binary mode. ios::trunc – erases all the data in the existing file. The above modes can be combined with the OR operator in order to have more than one effect. The default values for this modes are ios::in for ifstream, ios::out|ios::trunc for ofstream ios::in|ios::out for input/output fstream. If instead of the default second argument for ofstream, the ios::app is used with any other mode but the ios::trunc, the existing data in the file will be preserved during output. Let us now consider the following program to see how creation of streams, association with streams, working on the files and dissociation is done. Program 4.12[Correct].cpp In the above program, the fstream file is included on line 2. On line 5, an input stream input is created. On line 6, an output stream output is created. After that, on line 7, input is associated with a file name Input1.txt. This file exists in a directory named files which by itself exists in the working directory of the program. Therefore, the whole path is passed as an argument during the association. Note that two back-
  • 24. By: Asaye Chemeda Email: asayechemeda@yahoo.com 69 slashes are required to change directory: one the escape operator the other the actual back-slash. On line 8, output is associated with a file named Output1. This file exists in the same directory as Input1. Two arguments are passed for the open function during the association. The second argument ios::app overrides the default arguments ios::out|ios::trunc. As a result, when an output is sent to the output file, the original content will not be erased. Rather, an output will be appended to the existing data. The if-statement between line 9 and 11 checks whether the Input1 file exists or not. If the file exists in the specified directory, input will evaluate true. Otherwise, it evaluates false. If the case is the latter one, the program displays the message “The file doesn’t exist!”. On line 12, the first data is sent to the output file by using the insertion operator on output. The string “The first output message!” will be sent to the file. If the output file has already other data, the string will be appended to the existing data. This is due to the second argument passed to the open function. On line 13, the string “This one is appended!” will be appended to string sent on line 12. On lines 14 and 15, input and output are dissociated from the files which they have been interacting with. After this, the streams can be associated with other files for further I/O operations. Isn’t file I/O so simple? It even makes the basic principle of C++ I/O operations more clear. Do you also feel the same? Or do you want to wonder more? Let us now have a look at other functions which are frequently used in file I/O. In program 4.12, we have seen how the existence of an input file is checked by using the input stream itself. There is also another way to do this. In addition, what if we want to check an output file exists or not. The identifier of an output stream cannot be used in the same way as the identifier of the input stream was used to check whether an output file exists or not. In those cases, C++ has a built-in function which checks the existence of an input file. This function will be the next topic. The is_open function A member of the fstream, ifstream and ofstream classes, is_open function, checks whether a stream is associated with an existing file or not. It works with any stream and is invoked by the stream using the member access operator. The function takes no arguments returns true if the stream is associated with an existing file or false otherwise. The syntax to use the function is: In the above statement, the is_open function returns true if stream (which can be any stream) is associated with an existing file or false otherwise. Once we have seen how we can check whether a file exists or not, let us focus on the functions which are often used for operations on files. One of the most frequent operations on input files is to check whether the end of the file (EOF) is reached or not during extraction. Because extracting data from input file usually takes place until EOF is reached. One of the ways to do this is to use the input stream identifier in a logical expression. But, is there another way? The following topic answers this. The eof function A member of the ios class, eof function, returns true when end of file is reached or false otherwise. The function is invoked by a stream with the member access operator. The syntax to use the eof function is: The above statement will evaluate to true when EOF is reached in the file associated with stream. Therefore, an input stream should only extract as long as negation of the above statement returns true. Since an attempt by a program to perform input operation beyond EOF results in an error, detecting whether an EOF is reached or not is a common activity in dealing with reading data from files. Normally, the I/O operation on files takes place in sequential order. But, what if we are interested to point to specific location where the next I/O operation will take place within a file? Or what if it is desired get the current location where I/O operation is taking place? The next topic gives clues about these. The seekg,seekp,tellg and tellp functions The seekg and seekp functions respectively are members of the ifstream and ofstream classes which are used to point a specific location in the files associated with the respective streams. The seekg function is called get pointer and the seekp function is known as put pointer. Both the functions take two arguments. In both functions, the first argument specifies an integer offset from the file location specified in the second argument. The value offset represents the number of bytes to be passed from the location specifier to the next point. The syntax for the functions is as follows: