Saturday, 4 July 2015

INPUT/ OUTPUT STREAMS

9.1 C++ STREAMS:

The I/O system in C++ is designed to work with a wide variety of devices including terminals, disks, and tape drives. Although each device is very different; the I/O system supplies an interface to the programmer that is independent of the actual device being accessed. This interface is known as stream.

A stream is a sequence of bytes. It acts either as a source from which the input data can be obtained or as a destination to which the output data can be sent. The source stream that provides data to the program is called the input stream and the destination stream that receives output from the program is called the output stream. In other words, a program extracts the bytes from input stream and inserts bytes into an output stream. The data in the input stream can come from the keyboard or any other storage device. Similarly, the data in the output stream can go to the screen or any other storage device. As mentioned earlier, a stream acts as an interface between the program and the input/output device handles data (input or output) independent of the devices used.
C++ contains several pre-defined streams that are automatically opened when a program begins its execution. These include cin and cout, which have been used very often in our earlier programs. We know that cin represents the input stream connected to the standard input device (usually the keyboard) and cout represents the output stream connected to the standard output device (usually the screen). Note that the keyboard and the screen are default options. We can redirect streams to other devices or files, if necessary.

9.2 C++ Stream Classes:  

The C++ I/O system contains a hierarchy of classes that are used to define various streams to deal with both the console and disk files. These classes are called stream classes. Figure shows the hierarchy of the stream classes used for input and output operations with the console unit. These classes are declared in the header file iostream.h. This file should be included in all the programs that communicate with the console unit.

9.3 Unformatted I/O Operations:


Overloaded Operators >> and <<: We have used the objects cin and cout (pre-defined in the iostream.h file) for the input and output of data of various types. This has been made possible by overloading the operators >> and << to recognize all the basic C++ types. The >> operator is overloaded in the istream class and << is overloaded in the ostream class. The following is the general format for reading data from the keyboard:

cin >> variable1  >> variable2 >>…… >> variableN;

variable1, varible2, ...are valid C++ variable names that have been declared already. This statement will cause the computer to stop the execution and look for input data from the keyboard. The input data for this statement would be:

data1, data2 ………data N

The input data are separated by white spaces and should match the type of variable in the cin list. Spaces, newlines and tabs will be skipped.

The operator >> reads the data character by character and assigns it to the indicated location. The reading for a variable will be terminated at the encounter of a white space or a character that does not match the destination type. For example, consider the following code:
int code;
cin >> code;

Suppose the following data is given as input:
4258D

The operator will read the characters up to 8 and the value 4258 is assigned to code. The character D remains in the input stream and will be input to the next cin statement.

The general form for displaying data on the screen is:

cout << item1 << item2 << ..,. << itemN;

The items item1 through itemN may be variables or constants of any basic type. We have used such statements in a number of examples illustrated in previous chapters.

put() and get() Functions: The classes istream and ostream define two member functions get( ) and put( ) respectively to handle the single character input/output operations. There are two types of get( ) functions. We can use both get(char *) and get(void) prototypes to fetch a character including the blank space, tab and the newline character. The get(char *) version assigns the input character to its argument and the get(void) version returns the input character.

Since these functions are members of the input/output stream classes, we must invoke them using an appropriate object. For example:

char c;
cin.get(c);                    // get a character from keyboard and assign it to c
while(c!= '\n') {
cout << c;        // display the character on screen
cin.get(c);        // get another character
                        }

This code reads and displays a line of text (terminated by a newline character). The operator >> can also be used to read a character but it will skip the white spaces and newline character. The above while loop will not work properly if the statement.
cin >> c;
is used in place of
cin.get(c);
Try using both of them and compare the results.

The get(void) version is used as follows:
            ……
char c;
c = cin.get( );               // cin.get(c); replaced
            ……
            ……

The value returned by the function get( ) is assigned to the variable c.
The function put( ), a member of ostream class, can be used to output a line of text, character by character. For example,

cout.pt('x');
displays the character x and

cout.put(ch);
displays the yalue of variable ch.

The variable ch must contain a character value. We can also use a number as an argument to the function put( ). For example,

cout.put(68);
displays the character D. This statement will convert the int value 68 to a char value and display the character whose ASCII value is 68. The following segment of a program reads a line of text from the keyboard and displays it on the screen.

char c;
cin.get(c);                    II read a character
while(c != '\n') {
cout.put(c);                  II display the character on screen
cin.get(c);
}

Program illustrates the use of these two character-handling functions.
void main( )
{          int count = 0;
char c;
cout << "INPUT TEXT\n" ;
cin.get(c);
while(c != '\n') {
cout.put(c);
count ++;
cin.get(c); 
            }
cout << "\nNumber of characters = “ << count << “\n"; 
}
When we type a line of input, the text is sent to the program as soon as we press the RETURN key. The program then reads one character at a time using the statement cin.get(c); and displays it using the statement cout.put(c);. The process is terminated when the newline character is encountered.

getline( ) and write( ) Functions: We can read and display a line of text more efficiently using the line-oriented input/output functions getline( ) and write( ). The getline( ) function reads a whole line of text that ends with a newline character (transmitted by the RETURN key). This function can be invoked by using the object cin as follows:
cin.getline(line, size);  

This function call invokes the function getline( ) which reads character input into the variable line . The reading is terminated as soon as either the newline character '\n ' is encountered or size-1characters are read (whichever occurs first). The newline character is read but not saved. Instead, it is replaced by the null character. For example, consider the following code:

char name[20];
cin.getline(name,20);

Assume that we have given the following input through the keyboard:

Bjarne Stroustrup <press RETURN>

This input will be read correctly and assigned to the character array name. Let us suppose the input is as follows:

Object Oriented Programming <press RETURN >

In this case, the input will be terminated after reading the following 19 characters:

Object Oriented Pro


The two blank spaces contained in the string are also taken into account.
We can also read strings using the operator >> as follows:

cin >> name;

But cin can read strings that do not contain white spaces. This means that cin can read just one word and not a series of words such as "Bjarne Stroustrup". But it can read the following string correctly:

Bjarne_Stroustrup

After reading the string, cin automatically adds the terminating null character to the character array.

// Program to demonstrate cin and getline( )
# include <iostream.h>
void main( )
{
int size = 20;
char city [20];
cout << "Enter city name: \n";
cin >> city:
cout << "City name:" << city << "\n\n":'
cout << "Enter city name again: \n";
cin.getline(city, size);
cout << “City name now: " << city << "\n\n";
cout << “Enter another city name: \n”;
cin.getline(city, size):
cout << “ New city name:” << city << “\n\n";
}

The write( ) function displays an entire line and has the following form:
                       
cout.write(line,size);

The first argument line represents the name of the string to be displayed and the second argument size indicates the number of characters to display. Note that it does not stop displaying the characters automatically when the null character is encountered. If the size is greater than the length of line, then it displays beyond the bounds of line. Program below illustrates how write( ) method displays a string.

#include <iostream.h>
#include <string.h>
void main ( )
{
char * stringl = "C++ ";
char * string2 = "Programming” ;
int m = strlen(stringl);
int n = strlen(string2) ;

for(int i = 1; i < n; i++) 
{          cout.write(string2, i); cout << "'n";     }
for(i = n; i > 0; i--) 
{          cout.write(string2. i); cout << "'n";     }

cout.write(string1, m) .write(string2. n);
cout <<"n";
cout.write(stringl. 10);
}
The statement
cout.write(string1, 10);

displays more characters than what is contained in stringl. It is possible to concatenate two strings using the write( ) function. The statement

cout.write(string1, m).write(string2, n);

is equivalent to the following two statements:

cout.write(string1, m);
cout.write(string2, n);




9.4 Formatted Console I/O Operations

C++ supports a number of features that could be used for formatting the output. These features include:
  • ios class functions and flags
·         Manipulators.
  • User-defined output functions.

The ios class contains a large number of member functions that would help us to format the output in a number of ways. The most important ones among them are listed in Table 

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

precision( )                  To specify the number of digits to be displayed after the
decimal point of a float value.

fill( )                            To specify a character that is used to fill the unused portion of a
field.

setf( )                           To specify format flags that can control the form of output
display (such as left-justification and right-justification).

unsetf( )                       To clear the flags specified.

Manipulators are special functions that can be included in the I/O statements to alter the format parameters of a stream. Table shows some important manipulator functions that are frequently used. To access these manipulators, the file iomanip.h should be included in the program.

Table Manipulators
Manipulators               Equivalent ios function
setw( )                                     width( )
setprecision( )              precision( )
setfill( )                        fill( )
setiosflags( )                setf( )
resetiosflags( )             unsetf( )

In addition to these functions supported by the C++ library, we can create our own manipulator functions to provide any special output formats. The following sections will provide details of how to use the pre-defined formatting functions and how to create new ones.

width( ): We can use the width( ) function to define the width of a field necessary for the output of an item. Since, it is a member function, we have to use an object to invoke it, as shown below:

cout.width (w); 
where w is the field width (number of columns). The output will be printed in a field of w characters wide at the right end of the field. The width( ) function can specify the field width for only one item (the item that follows immediately). After printing one item (as per the specifications) it will revert back to the default. For example, the statements

cout.width(5);
cout << 543 << 12 << " \n";


The value 543 is printed right-justified in the first five columns. The specification width(5) does not retain the setting for printing the number 12. This can be improved as follows:

cout.width(5);
cout << 543;
cout.width(5);
cout << 12 << " \n";


The field width should be specified for each item separately. C++ never truncates the values and therefore, if the specified field width is smaller than the size of the value to be printed, C++ expands the field to fit the value. Program demonstrates how the function width( ) works.

#include <iostream.h>
void main( )
{
int items[4) = 110, 8, 12, 151 ;
int cost[4] = 175, 100, 60, 991 ;
cout.width(5) ;
cout < < "ITEMS" ;
cout.width(8);
cout < < "COST" ;
cout.width(15);
cout < < "TOTAL VALUE" < < "\n" ;

int sum = 0;
for(int i = 0; i < 4; i++) 
{
cout.width(5);                         cout << items(i);
cout.width(8);                         cout << cost[i];
int value = items[i ] * cost[i];
cout.width(15) ;          cout << value << "\n";
sum = sum + value;
            }
            cout < < " \n Grand Total = " ;
cout.width(2) ; cout << sum << "\n"; 3
}

Note that a field of width two has been used for printing the value of sum and the result is not truncated.

Setting Precision: precision( ): By default, the floating numbers are printed with six digits after the decimal point. However, we can specify the number of digits to be displayed after the decimal point while printing the floating-point numbers. This can be done by using the precision( ) member function as follows:

cout.precision(d);

where d is the number of digits to the right of the decimal point. For example, the statements

cout.precision(3);
cout << sqrt(2) << " \n";
cout << 3.14159 << “ \n";
cout << 2.50032 << " \n";

will produce the following output:
1.141 (truncated)
3.142 (rounded to the nearest point)
2.5 (no trailing zeros)

Note that, unlike the function width( ), precision( ) retains the setting in effect until it is reset. That is why we have declared only one statement for the precision setting, which is used by all the three outputs.
We can set different values to different precision as follows:

cout.precision(3);
cout << sqrt(2) << " \n";
cout.precision(5);                    //Reset the precision
cout << 3.14159 << " \n";

We can also combine the field specification with the precision setting. Example:

cout.precision(2);
cout.width(5);
cout << 1.2345;


Program shows how the functions width( ) and precision( ) are jointly used to control the output format.
#include<iostream.h>
#include <math.h>
void main( )
{
cout << "Precision set to 3 digits \n\n” ;
cout.precision(3) ;
cout.width(10);
cout << "VALUE” ;
cout.width(15);
cout << "SQRT OF VALUE" << "\n" ;
for(int n = 1; n-<= 5; n++)
{
cout.width(8) ;
cout << n;
cout.width(13);
cout << sqrt(n) << "\n"; 
            }
cout << "\n Precision set to 5 digits \n\n” ;
cout.precision(5);        //precision parameter changed
cout << " sqrt(10) = " << sqrt(10) << "\n\n”;
cout.precision(0);        //precision set to default
cout << " sqrt(10) = 0. << sqrt(10) << " (default setting)\n"; I
}
Here is the output of Program 
Precision set to 3 digits
VALUE          SQRT-OF-VALUE
1                                                                1
2                                                                1.414
3                                                                1.732
4                                                                 2
5                                                                 2.236
Precision set to 5 digits
sqrt(10) = 3.16228
sqrt(10) = 3.162278 (default setting)

Observe the following from the output:
  1. The output is rounded to the nearest cent (i.e., 1.6666 will be 1.67 for two digit       precision but 1.3333 will be 1.33).
  2. Trailing zeros are truncated.
  3. Precision setting stays in effect until it is reset.
  4. Default precision is 6 digits.

Filling and Padding fill(): We have been printing the values using much larger field widths than required by the values. The unused positions of the field are filled with white spaces, by default. However, we can use the fill( ) function to fill the unused positions by any desired character. It is used in the following form:

cout.fill(ch);
Where ch represents the character which is used for filling the unused positions. Example:
cout.fill(“*”);
cout.width(10);
cout << 5250 << "\n";


Financial institutions and banks use this kind of padding while printing cheques so that no one can change the amount easily. Like precision( ), till( ) stays in effect till we change it.

# include <iostream.h>
void main( )
{
cout.fill('<');
cout.precision(3) ;
for(int n = 1; n <= 6; n++)
{
cout.wid.th (5) ;
cout << n;
cout.width(10) ;
cout << 1.0 / float(n) << "\n";
if(n == 3) cout.fill('>');
            }
            cout << "\nPadding changed \n\n";
cout.fill('#');                 // fill() reset
cout.width(15) ;
cout << 12.345678 << "\n";
}


















Exercise:

  1. Write a program, which reads a text from the keyboard and displays the following details.
    1. Number of lines
    2. Number of characters
    3. Number of words

  1. Design a program to provide the following output specification for printing float vales.
    1. 10 columns width
    2. Right-justified
    3. Two digits precision
    4. Filling of unused places with *

  1. Write a program to display the details as shown below:

NAME                                    CODE                         COST
Turbo C++                  1001                            250.50
C primer                      890                              350.00
Java                             1120                            550.90