Online Book Reader

Home Category

Professional C__ - Marc Gregoire [269]

By Root 1317 0
still be written to the console because the use of cin immediately flushes the cout buffer; they are linked together in this way.

If you get confused between << and >>, just think of the angles as pointing toward their destination. In an output stream, << points toward the stream itself because data is being sent to the stream. In an input stream, >> points toward the variables because data is being stored.

Input Methods

Just like output streams, input streams have several methods that allow a lower level of access than the functionality provided by the more common >> operator.

get()

The get() method allows raw input of data from a stream. The simplest version of get()returns the next character in the stream, though other versions exist that read multiple characters at once. get() is most commonly used to avoid the automatic tokenization that occurs with the >> operator. For example, the following function reads a name, which can be made up of several words, from an input stream until the end of the stream is reached:

string readName(istream& inStream)

{

string name;

while (inStream.good()) {

int next = inStream.get();

if (next == EOF)

break;

name += next;// Implicitly convert to a char and append.

}

return name;

}

Code snippet from Get\Get.cpp

There are several interesting observations to make about this readName() function:

Its parameter is a non-const reference to an istream, not a const reference. The methods that read in data from a stream will change the actual stream (most notably, its position), so they are not const methods. Thus, you can’t call them on a const reference.

The return value of get() is stored in an int, not in a char. Because get() can return special non-character values such as EOF (end-of-file), ints are used. When next is appended to a string, it is implicitly converted to a char, and when it is appended to a wstring, it is converted to a wchar_t.

readName() is a bit strange because there are two ways to get out of the loop. Either the stream can get into a “not good” state, or the end of the stream is reached. A more common pattern for reading from a stream uses a different version of get() that takes a reference to a character and returns a reference to the stream. This pattern takes advantage of the fact that evaluating an input stream within a conditional context will result in true only if the stream is available for additional reading. Encountering an error or reaching the end-of-file both cause the stream to evaluate to false. The underlying details of the conversion operations required to implement this feature are explained in Chapter 18. The following version of the same function is a bit more concise:

string readName(istream& inStream)

{

string name;

char next;

while (inStream.get(next)) {

name += next;

}

return name;

}

Code snippet from Get\Get.cpp

unget()

For most purposes, the correct way to think of an input stream is as a one-way chute. Data falls down the chute and into variables. The unget() method breaks this model in a way by allowing you to push data back up the chute.

A call to unget() causes the stream to back up by one position, essentially putting the previous character read back on the stream. You can use the fail() method to see if unget() was successful or not. For example, unget() can fail if the current position is at the beginning of the stream.

The getReservationData() function seen earlier in this chapter did not allow you to enter a name with white space. The following code uses unget() to allow white space in the name. The code reads character by character and checks whether the character is a digit or not. If the character is not a digit, it is added to guestName. If it is a digit, the character is put back into the stream using unget(), the loop is stopped, and the >> operator is used to input an integer, partySize. The meaning of noskipws is discussed later in the section “Input Manipulators.”

void getReservationData()

{

string guestName;

int partySize = 0;

// Read letters until we find a non-letter

char

Return Main Page Previous Page Next Page

®Online Book Reader