23.2 — Input with istream

The iostream library is fairly complex -- so we will not be able to cover it in its entirety in these tutorials. However, we will show you the most commonly used functionality. In this section, we will look at various aspects of the input class (istream).

The extraction operator

As seen in many lessons now, we can use the extraction operator (>>) to read information from an input stream. C++ has predefined extraction operations for all of the built-in data types, and you’ve already seen how you can overload the extraction operator for your own classes.

When reading strings, one common problem with the extraction operator is how to keep the input from overflowing your buffer. Given the following example:

what happens if the user enters 18 characters? The buffer overflows, and bad stuff happens. Generally speaking, it’s a bad idea to make any assumption about how many characters your user will enter.

One way to handle this problem is through use of manipulators. A manipulator is an object that is used to modify a stream when applied with the extraction (>>) or insertion (<<) operators. One manipulator you have already worked with is "std::endl", which both prints a newline character and flushes any buffered output. C++ provides a manipulator known as setw (in the iomanip.h header) that can be used to limit the number of characters read in from a stream. To use setw(), simply provide the maximum number of characters to read as a parameter, and insert it into your input statement like such:

This program will now only read the first 9 characters out of the stream (leaving room for a terminator). Any remaining characters will be left in the stream until the next extraction.

Extraction and whitespace

The one thing that we have omitted to mention so far is that the extraction operator works with “formatted” data -- that is, it skips whitespace (blanks, tabs, and newlines).

Take a look at the following program:

When the user inputs the following:

Hello my name is Alex

The extraction operator skips the spaces and the newline. Consequently, the output is:


Oftentimes, you’ll want to get user input but not discard whitespace. To do this, the istream class provides many functions that can be used for this purpose.

One of the most useful is the get() function, which simply gets a character from the input stream. Here’s the same program as above using get():

Now when we use the input:

Hello my name is Alex

The output is:

Hello my name is Alex

std::get() also has a string version that takes a maximum number of characters to read:

If we input:

Hello my name is Alex

The output is:

Hello my n

Note that we only read the first 10 characters (we had to leave one character for a terminator). The remaining characters were left in the input stream.

One important thing to note about get() is that it does not read in a newline character! This can cause some unexpected results:

If the user enters:


The program will print:


and then terminate! Why didn’t it ask for 10 more characters? The answer is because the first get() read up to the newline and then stopped. The second get() saw there was still input in the cin stream and tried to read it. But the first character was the newline, so it stopped immediately.

Consequently, there is another function called getline() that works exactly like get() but reads the newline as well.

This code will perform as you expect, even if the user enters a string with a newline in it.

If you need to know how many character were extracted by the last call of getline(), use gcount():

A special version of getline() for std::string

There is a special version of getline() that lives outside the istream class that is used for reading in variables of type std::string. This special version is not a member of either ostream or istream, and is included in the string header. Here is an example of its use:

A few more useful istream functions

There are a few more useful input functions that you might want to make use of:

ignore() discards the first character in the stream.
ignore(int nCount) discards the first nCount characters.
peek() allows you to read a character from the stream without removing it from the stream.
unget() returns the last character read back into the stream so it can be read again by the next call.
putback(char ch) allows you to put a character of your choice back into the stream to be read by the next call.

istream contains many other functions and variants of the above mentioned functions that may be useful, depending on what you need to do. However, those topics are really more suited for a tutorial or book focusing on the standard library (such as the excellent “The C++ Standard Library” by Nicolai M. Josuttis).

23.3 -- Output with ostream and ios
23.1 -- Input and output (I/O) streams

73 comments to 23.2 — Input with istream

  • Yolo

    From what i noticed there is one more difference between get and getline. In the following snipet:

    If you enter more than 10 characters in the first stream. The rest of the characters dont get redirected to the second stream either, but in get they do. Am i wrong?

    • Yolo

      Sorry i copied the wrong text.

  • yeokaiwei


    1. I think there is a typo error with #include <iomanip.h>.

    It think it should be #include <iomanip>.


  • Chris

    The following sentence could possible be omitted or reformulated (especially the 'extensively')
    "One manipulator you have already worked with extensively is "std::endl"

    since the newest versions of this cpp-tutorial uses '\n', not std::endl.

  • sv

    there are few typos in above examples, 'endl' instead of 'std::endl'
    maybe they are intentional...i don't know

  • Hal

    Why does the loop

    loop infinitely? Is it because whatever the flag std::cin raises when it is empty is not evaluated as ``false``? If this is so, do you know why is this the case?

    If this is not the case, what does remain in std::cin preventing the extraction to be evaluated as ``false``? I imagine the EOL character is a candidate.

    But this rises a third---and last---question: why can the user still input text? While the loop is evaluating std::cin, the latter seems to behave like an open sink taking whatever we throw in.

    Thank you in advance. I understand you may have little time to answer. :)

  • AbraxasKnister

    The chapter uses the `using namespace std;` directive, which has been declared to be considered bad style in a previous chapter (it's of course ok to do so just for the sake of brevity).

    • nascardriver

      Not ok, chapter updated. Judging by your speed, you're done with the tutorials by now. Thanks again for all the mistakes you've pointed out, it'll make the journey easier for everyone who comes after you :)

      • AbraxasKnister

        Yes, I'm through and can only thank the both of you for the incredibly helpful content. Being explicitly told the "Do"s and "Don't"s on a certain level of credibility and range is rare and I can only celebrate having found an instance by reading it.

        I won't be gone though, I'm writing my masters thesis atm (which is quite focused on numerics) and will need an unhealthy amount of cpp for that. Already needed an operator overloading refresher for typecasting.

  • Sapinder

    Wherever I see on google, there is one word that I'm unable to make sense of- "flushing". In this simple program-

    they say 'endl' prints '\n' and then flushes the stream.
    What does it even mean to 'flush' the stream in reference to the above code?

    • nascardriver

      The string "Hello\n" is gets stored in an internal buffer by `std::cout`. At some point in the future (Maybe immediately), the string will be printed to the console and the buffer gets cleared. The "printing and clearing" part is the flush.
      With `std::endl`, you're forcing `std::cout` to flush immediately, ie. print now and clear the buffer now. That's slow, especially when you call `std::cout <<` multiple times or write to a file.

      • Sapinder

        Excuse me for frequent questions. :-|
        What happens in case of '\n'? Doesn't it flush immediately? When would it flush?

        • nascardriver

          `std::cout` flushes when you use `std::cin`, `std::cerr`, an when `std::cout` dies, ie. at the end of the program. There can be more calls to `flush`, but those are implementation-defined, eg. it's valid for an implementation to flush every time you print '\n'.
          It's rare that you need to flush manually. Long-running operations can make you want to flush manually, eg.

          At least on my machine, this program prints "start", waits 5 seconds, then prints "0 1 2 3 4". If I wanted to print a number every second, I'd have to flush the stream, ie. add `<< std::flush;` to line 11.

  • Parsa

    Im kind of confused. If the sole purpose of operator>> and other istream functions are to get whats inside of the stream, how come it gives the user a chance to put stuff into the stream?

    • nascardriver

      I'm not sure I understand your question.
      `operator>>` extracts data from the stream, it doesn't insert anything.
      `operator<<` inserts data into the stream. An overloaded `operator>>` could be used to insert data, but that would be wildly confusing and shouldn't be done.

Leave a Comment

Put all code inside code tags: [code]your code here[/code]