C++ Streams
C++ Streams
- We’ve seen how C I/O (input/output) routines (printf, scanf) can be used in
C++ programs
- This is perfectly valid since C is a subset of C++
- In addition to the C I/O routines, C++ supports a more object-oriented I/O facility
- This facility uses features of object-oriented programming such as overloading and
inheritance
- Not a built-in system to C++, rather part of a standard library (of classes)
Stream
- A stream can be defined simply as a flow of data (sequence of bytes) between devices
- In input operations, bytes flow from some device (i.e. keyboard, disk, network, ...) to
memory
- In output operations, bytes flow from memory to some device (i.e. screen, disk, network,
printer, ...)
Stream Operators
- C++ stream classes employ the use of overloaded operators for I/O processing as in the
following example
- We know (from overloading studies), that a function is associated with the << operator when
processed
- The operators << and >> (chosen by the class developers) are overloaded to perform
stream I/O
- You might recognize that these operators are also used in C to shift individual bits
- When used with C++ streams, however, they are overloaded to perform a different task
- This dual usage (bit operators and I/O streams) is one of the unique features of overloading
- With C++ streams, the >> operator performs input and the << operator performs output
- In C++, << and >> are also referred to as the stream insertion and stream extraction
operators
- Which class contains the overloaded << function called when the statement above is
processed?
- Recall that the operands of such a statement are used to determine the appropriate
overloaded function
- For example, the operand associated with the addition operator below is a Fraction object
Fraction f1;
f1 + 2;
- The Fraction class must contain the operator function to define how to add an integer to
a Fraction
- Our C++ output statement (repeated below) is examined in the exact same manner
Stream Objects
- The variable cout in the statement above is a predefined object from one of the C++
stream classes
- This and other stream objects are externally defined in the C++ stream class header files
- We’ve seen how C++ streams are implemented in a standard library of supplied classes
- As with our classes, header files containing the class declarations must be included in
programs
- To use C++ stream classes, we must include the appropriate header files in our programs
- The standard library organizes its class declarations in the header files described below
- Included with the class declarations are external definitions for the stream objects (cout,
cin, cerr)
- It is important to recognize that these are simply objects from different C++ stream classes
- Note how the “.h” extension is no longer necessary for C++ standard library classes
<iostream>
Declares basic services required for all stream-I/O operations
Externally defines the following stream objects
<iomanip>
Declares services useful to perform formatted I/O
<fstream>
Declares services for file processing operations
C C++
- Note the use of the special stream manipulator endl to indicate a new line in a stream
- Note the inclusion of the following statement
- This instructs the compiler to use specific naming conventions used in the C++ standard
library (std)
- As we’ll see later, this statement uses a feature included in the standard library called
a namespace
- Without this statement, the compiler will not recognize cout, cin and endl
- Stream objects can be used to process I/O in a very elegant manner as in the following
example
#include <iostream>
using namespace std;
main()
{
float price;
int qty;
Output
Enter part quantity: 5
Enter price of part: $10
Total order comes to : $50
- Note how stream operators can be chained together as in the last statement
- Note also that there exists a default conversion of the built-in types to strings in output
- To customize output format, C++ provides facilities for user-specified formatting
Stream Formatting
- cin and cout use default formatting defined in overloaded operator methods
- Using special I/O manipulators, we can specify a wide variety of custom formatting
- I/O manipulators, part of the C++ I/O stream library, are used with the header file, iomanip
- In many cases, we can use either a manipulator function or an associated class member
function
- Let’s look at two examples of custom formatting specifying floating-point precision and field
width
- Consult the C++ reference book for a complete list of all the available formatting options
- The site cplusplus.com provides an excellent reference for streams (and other C++
resources)
Floating-point precision
- Sets precision for all subsequent operations
- Manipulator function: setprecision
- Member function: precision
#include <iostream>
using namespace std;
#include <iomanip>
#include <math.h> // C math functions
main()
{
float root2 = sqrt( 2.0 );
int i;
Output
Using member method...
1
1
1.4
1.41
1.414
1.4142
1.41421
1.414214
1.4142135
1.41421354
Using manipulator...
1
1
1.4
1.41
1.414
1.4142
1.41421
1.414214
1.4142135
1.41421354
Field Width
- Sets number of character positions in output (field width)
- If values processed are smaller, field is padded
- If values processed are larger, value is NOT truncated
- Sets field width for only the next value, set to 0 implicitly after use
- Values will be as long as they need to be with zero width
- Manipulator function: setw
- Member method: width
Example 1
#include <iostream>
using namespace std;
#include <iomanip>
main()
{
int i;
int itmp = 5;
string str("Hello");
Output
Hello
5
Hello
5
Hello
5
Hello
5
Hello
5
Hello
5
Hello
5
Hello
5
Hello
5
Example 2
#include <iostream>
using namespace std;
#include <iomanip>
main()
{
int i;
int itmp = 5;
string str( "Hello" );
Output
Hello
5
Hello
5
Hello
5
Hello
5
Hello
5
Hello
5
Hello
5
Hello
5
Hello
5
#include <iostream>
using namespace std;
main()
{
char c;
// Copy until end of input is reached
while( ( c = cin.get() ) != EOF )
cout.put( c );
Output
Hello
Hello
int qty;
cin >> qty;
- This operation will skip any input leading whitespace characters (tab, space)
- This operation will stop reading input when a whitespace character is encountered
- As a result, we cannot use this operation to read elements containing whitespaces (i.e.
spaces)
- Consider the following example where we only read the first name entered
#include <iostream>
using namespace std;
main()
{
string name;
cout << "Enter name (first last): ";
}
Output
Enter name (first last): John Doe
Your name: John
- The stream extraction operator is reading the first element and terminates at the blank
space
- If the number of elements are known, we can chain the stream extraction operator as in the
modified example
#include <iostream>
using namespace std;
main()
{
string firstName, lastName;
cout << "Enter name (first last): ";
- How does this example work? What do you think the operation cin >>
firstName returns?
- Since the overloaded input stream operation returns the stream object, we can chain calls
- What about if we don't know the number of elements to read beforehand?
- We could either use methods associated with the string class or the C++ stream class
Input stream class supplies a member function to read a line until a newline
character
#include <iostream>
using namespace std;
main()
{
cout << "Enter name (first last): ";
string name;
getline( cin, name );
Output
Enter name (first last): John Doe
Your name: John Doe
#include <iostream>
using namespace std;
main()
{
cout << "Enter sentence with a : character" << endl;
string str;
getline( cin, str, ':' );
cout << "You entered: " << str << endl;
}
Output
Enter sentence with a : character
This is a sentence:
You entered: This is a sentence
#include <iostream>
using namespace std;
main()
{
cout << "Enter name (first last): ";
char name[100];
cin.getline( name, 100 );
Output
Enter name (first last): John Doe
Your name: John Doe
#include <iostream>
using namespace std;
main()
{
int i;
string str;
cout << "Enter an integer: ";
cin >> i;
cout << "Integer is: " << i << endl;
cout << "Enter a string: ";
getline( cin, str );
cout << "String is: " << str << endl;
cin >> str;
cout << "String is: " << str << endl;
}
Output
Enter an integer: 1
Integer is: 1
Enter a string: String is:
hello
String is: hello
- What is happening in this example? Is the function getline skipping the string?
- cin will read until it sees a newline character
- cin stops before newline character (created by Enter key) and will NOT be read
- This newline character is still sitting on the input buffer waiting to be read
- The next getline statement will read this newline character
- Similarly, getline reads until a newline character
- The getline statement reads the newline and stops
- The string is now still sitting in the input buffer
- This string will be read with any subsequent input statements
cin.ignore()
- We can use this method to correct our string skipping problem above
#include <iostream>
using namespace std;
main()
{
int i;
string str;
cout << "Enter an integer: ";
cin >> i;
cout << "Integer is: " << i << endl;
cout << "Enter a string: ";
cin.ignore();
getline( cin, str );
cout << "String is: " << str << endl;
}
Output
Enter an integer: 1
Integer is: 1
Enter a string: hello
String is: hello
File Streams
- The C++ standard library also provides C++ classes to handle streams associated with files
- These classes define operations to read and write from and to files
- File stream classes do not provide pre-defined class objects similar to cin and cout
- Instead, we declare our own objects from file stream classes
- Use of these classes is provided with the header file <fstream>
- Three commonly used file stream classes
Class
Function
Name
ofstream Open file for output only
ifstream Open file for input only
fstream Open file for input or output
Example 1
#include <iostream>
using namespace std;
#include <iomanip>
#include <fstream>
main()
{
// Open file for output
ofstream outFile( "copy.out", ios::out );
char c;
while( ( c = cin.get() ) != '\n' )
outFile.put( char(c) );
outFile.close();
inFile.close();
}
Output
Type a sentence
CSC 125 is fun!
CSC 125 is fun!
- C++ stream classes, as we’ll see with inheritance, are related in a large class hierarchy
- At the top of this hierarchy is a base class (ios) which contains general functionality for all
classes
- ios::out, ios::in are enumeration constants from this base class
- These constants specify file operations (open for output, open for input)
- Could have also used stream operators with file stream objects by replacing
with
while( ( c = cin.get() ) != '\n' )
outFile << c;
Example 2
#include <iostream>
using namespace std;
#include <fstream>
main()
{
char c;
outFile.close();
file.close();
}
Output
Type a sentence
CSC 125 is fun!
CSC 125 is fun!
#include <iostream>
using namespace std;
class Point
{
private:
float x, y, z;
float size;
public:
// Constructor
Point( float c1=0.0, float c2=0.0, float c3=0.0 )
{
x = c1;
y = c2;
z = c3;
size = 0.0;
}
// Access methods
float setSize( float f )
{
size = f;
}
float getSize()
{
return size;
}
};
main()
{
Point p(1,2,3);
Output
The point info...
x, y, z: 1,2,3
size: 0