8.3.1. string Class I/O

Time: 00:01:53 | Download: Large, Large (CC), Small | Streaming, Streaming (CC) | Slides (PDF)

Previously, we explored the behavior of C-string console I/O. We discovered that the inserter operator, <<, worked well for C-string output. However, the extractor operator, >>, didn't work reliably for C-string input. Specifically, the extractor fails to read white space (spaces and tabs). You should note that this behavior results from the operators and not the kind of string used.

The following program repeats the simple program used to demonstrate the failure of the extractor when used with C-strings but with a string object as the target:

#include <iostream>
#include <string>
using namespace std;

int main()
{
	string	input;

	//cin >> input;			// stops reading at space
	//cout << input << endl;	
	getline(cin, input);		// discards \n
	cout << input << endl;


	return 0;
}
string object I/O example. The extractor operator, >>, again fails to read spaces into a string object just as it failed to read spaces into a C-string. In the earlier C-string example, we solved the problem with a function named getline, and we'll take the same approach here. But notice that we're using a different getline function here despite having the same name.

The following figure compares the two getline functions side by side to highlight their differences.

C-Stringstring Class
char input[100];
cin.getline(input, 100);
string input;
getline(cin, input);
cin
The input stream from which the data is read
100
The size of the character array storing the C-string
input
The name of the C-string. The function saves the string read from the console in this variable
cin
The input stream from which the data is read
input
The name of the string object. The string read from the console is stored in this object
C-string getline vs. string class getline. Both kinds of strings have a getline function that can read spaces embedded in strings. But they are different functions with different argument lists.
A picture illustrating the input stream, cin, before and after two read operations. The first operation begins with a '1,' '5,' and a newline character in the stream. The newline remains in the stream after reading the integer 15 with the extractor. The second operation shows a newline, the string 'Hello,' and a newline. Reading the input with getline removes the first newline, leaving the string and trailing newline.
#include <iostream>
#include <string>
using namespace std;

int main()
{
    int i1;
    cout << "Enter the first number: ";
    cin >> i1;

    string s1;
    cout << "Enter the first string: ";
    getline(cin, s1);
    cout << s1 << endl;

    return 0;
}
 
#include <iostream>
#include <string>
using namespace std;

int main()
{
    int i1;
    cout << "Enter a number: ";
    cin >> i1;
    cin.ignore();

    string s1;
    cout << "Enter the first string: ";
    getline(cin, s1);
    cout << s1 << endl;

    return 0;
}
#include <iostream>
#include <string>
using namespace std;

int main()
{
    string s1;
    cout << "Enter the first string: ";
    cin.ignore();
    getline(cin, s1);
    cout << s1 << endl;

    return 0;
}
 
 
 
 
(a)(b)(c)
Revisiting the newline problem with string objects. This is our third exploration of the newline problem but presented in the context of the C++ string class. It is logically identical to the C-string version, sharing its outline and solution. This version replaces C-strings and the corresponding header file and functions with the string class. As the user types characters on the keyboard, the system puts them in the input stream (cin). The user signals the program to read the characters by pressing the Enter key, which appends a newline at the end of the characters in the stream. The pictures illustrate the input stream during the read operations.
  1. The first input statement (light blue) reads an integer from the input stream but leaves the trailing newline character (i). The getline function (pink) reads and discards the leading newline character (ii), ending the call without reading a string.
  2. The cin statement (light blue) reads an integer but leaves the newline character in the input stream (i). The ignore function (pink) discards the leading newline (ii), allowing the getline (yellow) to read the string successfully.
  3. The behavior of example (b) tempts to adopt a simple strategy: always call ignore (pink) before getline (light blue). This simple program demonstrates that the strategy doesn't always work. Without a newline left from a previous input operation (i), the input stream looks similar to (ii) but without the leading newline. Therefore, the the ignore function discards the first character of the string, H, and the program saves and prints ello.