Tuesday 7 February 2017

Stream Classes / Notes - C++ Tutorials

During the development of C++ a new class-based input/output system was implemented. This gave rise to the I/O stream classes, which are now available in a library of their own, the so-called iostream library.
The class ios is the base class of all other stream classes. It contains the attributes and abilities common to all streams. Effectively, the ios class
• manages the connection to the physical data stream that writes your program's data to a file or outputs the data on screen
• contains the basic functions needed for formatting data. A number of flags that determine how character input is interpreted have been defined for this purpose.
The istream and ostream classes derived from ios form a user-friendly interface for stream manipulation. The istream class is used for reading streams and the ostream class is used for writing to streams. The operator >> is defined in istream and << is defined in ostream, for example.
The iostream class is derived by multiple inheritance from istream and ostream and thus offers the functionality of both classes.
The system I/O mechanisms should transfer bytes from devices to memory (and vice versa) consistently and reliably. Such transfers often involve some mechanical motion, such as the rotation of a disk or a tape, or the typing of keystrokes at a keyboard. The time these transfers take is typically much greater than the time the processor requires to manipulate data internally. Thus, I/O operations require careful planning and tuning to ensure optimal performance.
C++ provides both "low-level" and "high-level" I/O capabilities. Low-level I/O capabilities (i.e., unformatted I/O) specify that some number of bytes should be transferred device-to-memory or memory-to-device. In such transfers, the individual byte is the item of interest. Such low-level capabilities provide high-speed, high-volume transfers but are not particularly convenient for programmers.
Programmers generally prefer a higher-level view of I/O (i.e., formatted I/O), in which bytes are grouped into meaningful units, such as integers, floating-point numbers,characters, strings and user-defined types. These type-oriented capabilities are satisfactory for most I/O other than high-volume file processing.
Stream Output
Formatted and unformatted output capabilities are provided by ostream. Capabilities for output include output of standard data types with the stream insertion operator (<<); output of characters via the put member function; unformatted output via the write member function; output of integers in decimal, octal and hexadecimal formats; output of floating-point values with various precision, with forced decimal points, in scientific notation and in fixed notation; output of data justified in fields of designated widths; output of data in fields padded with specified characters; and output of uppercase letters in scientific notation and hexadecimal notation
Stream Input
Now let us consider stream input. Formatted and unformatted input capabilities are provided by istream. The stream extraction operator (i.e., the overloaded >> operator) normally skips white-space characters (such as blanks, tabs and newlines) in the input stream; later we will see how to change this behavior. After each input, the stream extraction operator returns a reference to the stream object that received the extraction message (e.g., cin in the expression cin >> grade). If that reference is used as a condition (e.g., in a while statement's loop-continuation condition), the stream's overloaded void * cast operator function is implicitly invoked to convert the reference into a non-null pointer value or the null pointer based on the success or failure of the last input operation. A non-null pointer converts to the bool value TRue to indicate success and the null pointer converts to the bool value false to indicate failure.
get and getline Member Functions
The get member function with no arguments inputs one character from the designated stream (including white-space characters and other non-graphic characters, such as the key sequence that represents end-of-file) and returns it as the value of the function call. This version of get returns EOF when end-of-file is encountered on the stream.
The blow program demonstrates the use of member functions eof and get on input stream cin and member function put on output stream cout. The program first prints the value of cin.eof()i.e., false (0 on the output)to show that end-of-file has not occurred on cin. The user enters a line of text and presses Enter followed by end-of-file (<ctrl>-z on Microsoft Windows systems, <ctrl>-d on UNIX and Macintosh systems).


#include <iostream>
using namespace std;
int main()
{
int character; // use int, because char cannot represent EOF
// prompt user to enter line of text
cout << "Before input, cin.eof() is " << cin.eof() << endl
<< "Enter a sentence followed by end-of-file:" << endl;
// use get to read each character; use put to display it
while ( ( character = cin.get() ) != EOF )
cout.put( character );
// display end-of-file character
cout << "\nEOF in this system is: " << character << endl;
cout << "After input of EOF, cin.eof() is " << cin.eof() << endl;
return 0;
} // end main

The get member function with a character-reference argument inputs the next character from the input stream (even if this is a white-space character) and stores it in the character argument. This version of get returns a reference to the istream object for which the get member function is being invoked.
A third version of get takes three argumentsa character array, a size limit and a delimiter (with default value '\n'). This version reads characters from the input stream. It either reads one fewer than the specified maximum number of characters and terminates or terminates as soon as the delimiter is read. A null character is inserted to terminate the input string in the character array used as a buffer by the program. The delimiter is not placed in the character array but does remain in the input stream (the delimiter will be the next character read). Thus, the result of a second consecutive get is an empty line, unless the delimiter character is removed from the input stream (possibly with cin.ignore()).
The below program compares input using stream extraction with cin (which reads characters until a white-space character is encountered) and input using cin.get. Note that the call to cin.get does not specify a delimiter, so the default '\n' character is used.


#include <iostream>
using namespace std;
int main()
{
// create two char arrays, each with 80 elements
const int SIZE = 80;
char buffer1[ SIZE ];
char buffer2[ SIZE ];
// use cin to input characters into buffer1
cout << "Enter a sentence:" << endl;
cin >> buffer1;
// display buffer1 contents
cout << "\nThe string read with cin was:" << endl
<< buffer1 << endl << endl;
// use cin.get to input characters into buffer2
cin.get( buffer2, SIZE );
// display buffer2 contents
cout << "The string read with cin.get was:" << endl
<< buffer2 << endl;
return 0;
} // end main

Using Member Function getline
Member function getline operates similarly to the third version of the get member function and inserts a null character after the line in the character array. The getline function removes the delimiter from the stream (i.e., reads the character and discards it), but does not store it in the character array. The below program demonstrates the use of the getline member function to input a line of text.

// Fig. 15.6: Fig15_06.cpp
// Inputting characters using cin member function getline.
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
int main()
{
const int SIZE = 80;
char buffer[ SIZE ]; // create array of 80 characters
// input characters in buffer via cin function getline
cout << "Enter a sentence:" << endl;
cin.getline( buffer, SIZE );
// display buffer contents
cout << "\nThe sentence entered is:" << endl << buffer << endl;
return 0;
} // end main

Example: Calling a manipulator
Here the manipulator showpos is called.
cout << showpos << 123; // Output: +123
The above statement is equivalent to
cout.setf( ios::showpos);
cout << 123;
The other positive numbers are printed with their sign as well:
cout << 22; // Output: +22
The output of a positive sign can be canceled by the manipulator noshowpos:
cout << noshowpos << 123; // Output: 123
The last statement is equivalent to
cout.unsetf( ios::showpos);
cout << 123;

Formatting
When reading keyboard input, a valid input format must be used to determine how input is to be interpreted. Similarly, screen output adheres to set of rules governing how, for example, floating-point numbers are displayed.
The stream classes istream and ostream offer various options for performing these tasks. For example, you can display a table of numeric values in a simple way.
In previous chapters we have looked at the cin and cout streams in statements such as:

cout << "Please enter a number: ";
cin >> x;

The following sections systematically describe the abilities of the stream classes. This includes:
• the >> and << operators for formatted input and output. These operators are defined for expressions with fundamental types—that is, for characters, boolean values, numbers and strings.
• manipulators, which can be inserted into the input or output stream. Manipulators can be used to generate formats for subsequent input/output. One manipulator that you are already familiar with is endl, which generates a line feed at the end of a line.
• other methods for determining or modifying the state of a stream and unformatted input and output.

Flags and Manipulators
Formatting flags defined in the parent class ios determine how characters are input or output. In general, flags are represented by individual bits within a special integral variable. For example, depending on whether a bit is set or not, a positive number can be output with or without a plus sign.
Each flag has a default setting. For example, integral numbers are output as decimals by default, and positive numbers are output without a plus sign.
It is possible to modify individual formatting flags. The methods setf() and unsetf() can be used for this purpose. However, the same effect can be achieved simply by using so-called manipulators, which are defined for all important flags. Manipulators are functions that can be inserted into the input or output stream and thus be called.

Sample program

// Reads integral decimal values and
// generates octal, decimal, and hexadecimal output.
#include <iostream> // Declarations of cin, cout and
using namespace std; // manipulators oct, hex, ...
int main()
{
int number;
cout << "Please enter an integer: ";
cin >> number;
cout << uppercase // for hex-digits
<< " octal \t decimal \t hexadecimal\n "
<< oct << number << " \t "
<< dec << number << " \t "
<< hex << number << endl;
return 0;
}

Formatting Options
The << operator can output values of type short, int, long or a corresponding unsigned type. The following formatting options are available:
• define the numeric system in which to display the number: decimal, octal, or hexadecimal
• use capitals instead of small letters for hexadecimals
• display a sign for positive numbers.
In addition, the field width can be defined for the above types. The field width can also be defined for characters, strings, and floating-point numbers, and will be discussed in the following sections.

Numeric System
Integral numbers are displayed as decimals by default. The manipulators oct, hex, and dec can be used for switching from and to decimal display mode.

Example:
cout << hex << 11; // Output: b

Hexadecimals are displayed in small letters by default, that is, using a, b, ..., f. The manipulator uppercase allows you to use capitals.

Example:
cout << hex << uppercase << 11; //Output: B

The manipulator nouppercase returns the output format to small letters.

Negative Numbers
When negative numbers are output as decimals, the output will always include a sign. You can use the showpos manipulator to output signed positive numbers.

Example:
cout << dec << showpos << 11; //Output: +11

You can use noshowpos to revert to the original display mode.
When octal or hexadecimal numbers are output, the bits of the number to be output are always interpreted as unsigned! In other words, the output shows the bit pattern of a number in octal or hexadecimal format.

Example:
cout << dec << -1 << " " << hex << -1;
This statement causes the following output on a 32-bit system:
-1 ffffffff

Formatted Output of Floating-Point Numbers
Sample program

#include <iostream>
using namespace std;
int main()
{
double x = 12.0;
cout.precision(2); // Precision 2
cout << " By default: " << x << endl;
cout << " showpoint: " << showpoint << x << endl;
cout << " fixed: " << fixed << x << endl;
cout << " scientific: " << scientific << x << endl;
return 0;
}

Standard Settings
Floating-points are displayed to six digits by default. Decimals are separated from the integral part of the number by a decimal point. Trailing zeroes behind the decimal point
are not printed. If there are no digits after the decimal point, the decimal point is not printed (by default).

Examples:
cout << 1.0; // Output: 1
cout << 1.234; // Output: 1.234
cout << 1.234567; // Output: 1.23457

The last statement shows that the seventh digit is not simply truncated but rounded. Very large and very small numbers are displayed in exponential notation.

Example:
cout << 1234567.8; // Output: 1.23457e+06

Formatting
The standard settings can be modified in several ways. You can
• change the precision, i.e. the number of digits to be output
• force output of the decimal point and trailing zeroes
• stipulate the display mode (fixed point or exponential).
Both the manipulator setprecision()and the method precision() can be used to redefine precision to be used.

Example:
cout << setprecision(3); // Precision: 3
// or: cout.precision(3);
cout << 12.34; // Output: 12.3

Note that the header file iomanip must be included when using the manipulator setprecision(). This also applies to all standard manipulators called with at least one argument.
The manipulator showpoint outputs the decimal point and trailing zeroes. The number of digits being output (e.g. 6) equals the current precision.

Example:
cout << showpoint << 1.0; // Output: 1.00000
However, fixed point output with a predetermined number of decimal places is often more useful. In this case, you can use the fixed manipulator with the precision defining the number of decimal places. The default value of 6 is assumed in the following example.

Example:
cout << fixed << 66.0; // Output: 66.000000
In contrast, you can use the scientific manipulator to specify that floating-point numbers are output as exponential

Output In Fields
Examples
#include <iostream> // Obligatory
#include <iomanip> // declarations
using namespace std;

1st Example: cout << '|' << setw(6) << 'X' << '|';
Output: | X| // Field width 6

2nd Example:cout << fixed << setprecision(2)
<< setw(10) << 123.4 << endl
<< "1234567890" << endl;
Output: 123.40 // Field width 10
1234567890

The << operator can be used to generate formatted output in fields. You can
• specify the field width
• set the alignment of the output to right- or left-justified
• specify a fill-character with which to fill the field.

Field Width
The field width is the number of characters that can be written to a field. If the output string is larger than the field width, the output is not truncated but the field is extended. The output will always contain at least the number of digits specified as the field width.
You can either use the width() method or the setw() manipulator to define field width.

Example:
cout.width(6); // or: cout << setw(6);
One special attribute of the field width is the fact that this value is non-permanent: the field width specified applies to the next output only, as is illustrated by the examples on the opposite page. The first example outputs the character 'X' to a field with width of 6, but does not output the '|' character.
The default field width is 0. You can also use the width() method to get the current field width. To do so, call width() without any other arguments.

Example:
int fieldwidth = cout.width();

Fill Characters and Alignment
If a field is larger than the string you need to output, blanks are used by default to fill the field. You can either use the fill() method or the setfill() manipulator to specify another fill character.

Example:
cout << setfill('*') << setw(5) << 12;
// Output: ***12

The fill character applies until another character is defined.
As the previous example shows, output to fields is normally right-aligned. The other options available are left-aligned and internal, which can be set by using the manipulators left and internal. The manipulator internal left-justifies the sign and right-justifies the number within a field.

Example:
cout.width(6); cout.fill('0');
cout << internal << -123; // Output: -00123

Output of Characters and Strings
Sample program
// Enters a character and outputs its
// octal, decimal, and hexadecimal code.
#include <iostream> // Declaration of cin, cout
#include <iomanip> // For manipulators being called
// with arguments.
#include <string>
using namespace std;
int main()
{
int number = ' ';
cout << "The white space code is as follows: "
<< number << endl;
char ch;
string prompt =
"\nPlease enter a character followed by "
" <return>: ";
cout << prompt;
cin >> ch; // Read a character
number = ch;
cout << "The character " << ch
<< " has code" << number << endl;
cout << uppercase // For hex-digits
<< " octal decimal hexadecimal\n "
<< oct << setw(8) << number
<< dec << setw(8) << number
<< hex << setw(8) << number << endl;
return 0;
}

Outputting Characters and Character Codes
The >> operator interprets a number of type char as the character code and outputs the corresponding character:

Example:
char ch = '0';
cout << ch << ' ' << 'A';
// Outputs three characters: 0 A

It is also possible to output the character code for a character. In this case the character code is stored in an int variable and the variable is then output.

Example:
int code = '0';
cout << code; // Output: 48

The '0' character is represented by ASCII Code 48. The program on the opposite page contains further examples.

Outputting Strings
You can use the >> operator both to output string literals, such as "Hello", and string variables, as was illustrated in previous examples. As in the case of other types, strings can be positioned within output fields.

Example:
string s("spring flowers ");
cout << left // Left-aligned
<< setfill('?') // Fill character ?
<< setw(20) << s ; // Field width 20

This example outputs the string "spring flowers??????". The manipulator right can be used to right-justify the output within the field.

Formatted Input
Sample program
// Inputs an article label and a price
#include <iostream> // Declarations of cin, cout,...
#include <iomanip> // Manipulator setw()
#include <string>
using namespace std;
int main()
{
string label;
double price;
cout << "\nPlease enter an article label: ";
// Input the label (15 characters maximum):
cin >> setw(16); // or: cin.width(16);
cin >> label;
cout << "\nEnter the price of the article: ";
cin >> price; // Input the price
// Controlling output:
cout << fixed << setprecision(2)
<< "\nArticle:"
<< "\n Label: " << label
<< "\n Price: " << price << endl;
// ... The program to be continued
return 0;
}

The >> operator, which belongs to the istream class, takes the current number base and field width flags into account when reading input:
• the number base specifies whether an integer will be read as a decimal, octal, or hexadecimal
• the field width specifies the maximum number of characters to be read for a string.
When reading from standard input, cin is buffered by lines. Keyboard input is thus not read until confirmed by pressing the <Return> key. This allows the user to press the backspace key and correct any input errors, provided the return key has not been pressed. Input is displayed on screen by default.

Input Fields
The >> operator will normally read the next input field, convert the input by reference to the type of the supplied variable, and write the result to the variable. Any white space characters (such as blanks, tabs, and new lines) are ignored by default.

Example:
char ch;
cin >> ch; // Enter a character

When the following keys are pressed
<return> <tab> <blank> <X> <return>

the character 'X' is stored in the variable ch.

An input field is terminated by the first white space character or by the first character that cannot be processed.

Example:
int i;
cin >> i;

Typing 123FF<Return> stores the decimal value 123 in the variable i. However, the characters that follow, FF and the newline character, remain in the input buffer and will be read first during the next read operation.
When reading strings, only one word is read since the first white space character will begin a new input field.

Example:
string city;
cin >> city; // To read just one word!

If Lao Kai is input, only Lao will be written to the city string. The number of characters to be read can also be limited by specifying the field width. For a given field width of n, a maximum of n–1 characters will be read, as one byte is required for the null character. Any initial white space will be ignored. The program on the opposite page illustrates this point and also shows how to clear the input buffer.

Formatted Input of Numbers
Sample program
// Enter hexadecimal digits and a floating-point number
//
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int number = 0;
cout << "\nEnter a hexadecimal number: " << endl;
cin >> hex >> number; // Input hex-number
cout << "Your decimal input: " << number << endl;
// If an invalid input occurred:
double x1 = 0.0, x2 = 0.0;
cout << "\nNow enter two floating-point values: " << endl;
cout << "1. number: ";
cin >> x1; // Read first number
cout << "2. number: ";
cin >> x2; // Read second number
cout << fixed << setprecision(2)<<"\nThe sum of both numbers:"
<< setw(10) << x1 + x2 << endl;
cout << "\nThe product of both numbers: " << setw(10)
<< x1 * x2 << endl;
return 0;
}

Inputting Integers
You can use the hex, oct, and dec manipulators to stipulate that any character sequence input is to processed as a hexadecimal, octal, or decimal number.

Example:
int n;
cin >> oct >> n;

An input value of 10 will be interpreted as an octal, which corresponds to a decimal value of 8.

Example:
cin >> hex >> n;

Here, any input will be interpreted as a hexadecimal, enabling input such as f0a or -F7.

Inputting Floating-Point Numbers
The >> operator interprets any input as a decimal floating-point number if the variable is a floating-point type, i.e. float, double, or long double. The floating-point number can be entered in fixed point or exponential notation.

Example:
double x;
cin >> x;

The character input is converted to a double value in this case. Input, such as 123, -22.0, or 3e10 is valid.

Unformattwd Input/Output
Sample program
// Reads a text with the operator >>
// and the function getline().
#include <iostream>
#include <string>
using namespace std;
string header =
" --- Demonstrates Unformatted Input ---";
int main()
{
string word, rest;
cout << header << "\n\nPress <return> to go on" << endl;
cin.get(); // Read the new line without saving.
cout << "\nPlease enter a sentence with several words!"
<< "\nEnd with <!> and <return>." << endl;
cin >> word; // Read the first word
getline( cin, rest, '!'); // and the remaining text
// up to the character !
cout << "\nThe first word: " << word << "\nRemaining text: "
<< rest << endl;
return 0;
}

Unformatted input and output does not use fields, and any formatting flags that have been set are ignored. The bytes read from a stream are passed to the program "as is." More
specifically, you should be aware that any white space characters preceding the input will be processed.

Reading and Writing Characters
You can use the methods get() and put() to read or write single characters. The get() method reads the next character from a stream and stores it in the given char variable.

Example:
char ch;
cin.get(ch);

If the character is a white space character, such as a newline, it will still be stored in the ch variable. To prevent this from happening you can use

cin >> ch;

to read the first non-white space character.
The get() method can also be called without any arguments. In this case, get() returns the character code of type int.

Example:
int c = cin.get();

The put() method can be used for unformatted output of a character. The character to be output is passed to put() as an argument.

Example:
cout.put('A');

This statement is equivalent to cout << 'A'; , where the field width is undefined or has been set to 1.

Reading a Line
The >> operator can only be used to read one word into a string. If you need to read a whole line of text, you can use the global function getline(), which was introduced earlier in this chapter.

Example:
getline(cin, text);

This statement reads characters from cin and stores them in the string variable text until a new line character occurs. However, you can specify a different delimiting character by passing the character to the getline() function as a third argument.

Example:
getline(cin, s, '.');

The delimiting character is read, but not stored in the string. Any characters subsequent to the first period will remain in the input buffer of the stream