Search

23.1 — Input and output (I/O) streams

Input and output functionality is not defined as part of the core C++ language, but rather is provided through the C++ standard library (and thus resides in the std namespace). In previous lessons, you included the iostream library header and made use of the cin and cout objects to do simple I/O. In this lesson, we’ll take a look at the iostream library in more detail.

The iostream library

When you include the iostream header, you gain access to a whole hierarchy of classes responsible for providing I/O functionality (including one class that is actually named iostream). The class hierarchy for the non-file-I/O classes looks like this:

The first thing you may notice about this hierarchy is that it uses multiple inheritance (that thing we told you to avoid if at all possible). However, the iostream library has been designed and extensively tested in order to avoid any of the typical multiple inheritance problems, so you can use it freely without worrying.

Streams

The second thing you may notice is that the word “stream” is used an awful lot. At its most basic, I/O in C++ is implemented with streams. Abstractly, a stream is just a sequence of bytes that can be accessed sequentially. Over time, a stream may produce or consume potentially unlimited amounts of data.

Typically we deal with two different types of streams. Input streams are used to hold input from a data producer, such as a keyboard, a file, or a network. For example, the user may press a key on the keyboard while the program is currently not expecting any input. Rather than ignore the users keypress, the data is put into an input stream, where it will wait until the program is ready for it.

Conversely, output streams are used to hold output for a particular data consumer, such as a monitor, a file, or a printer. When writing data to an output device, the device may not be ready to accept that data yet -- for example, the printer may still be warming up when the program writes data to its output stream. The data will sit in the output stream until the printer begins consuming it.

Some devices, such as files and networks, are capable of being both input and output sources.

The nice thing about streams is the programmer only has to learn how to interact with the streams in order to read and write data to many different kinds of devices. The details about how the stream interfaces with the actual devices they are hooked up to is left up to the environment or operating system.

Input/output in C++

Although the ios class is generally derived from ios_base, ios is typically the most base class you will be working directly with. The ios class defines a bunch of stuff that is common to both input and output streams. We’ll deal with this stuff in a future lesson.

The istream class is the primary class used when dealing with input streams. With input streams, the extraction operator (>>) is used to remove values from the stream. This makes sense: when the user presses a key on the keyboard, the key code is placed in an input stream. Your program then extracts the value from the stream so it can be used.

The ostream class is the primary class used when dealing with output streams. With output streams, the insertion operator (<<) is used to put values in the stream. This also makes sense: you insert your values into the stream, and the data consumer (eg. monitor) uses them.

The iostream class can handle both input and output, allowing bidirectional I/O.

Finally, there are a bunch of classes that end in “_withassign”. These stream classes are derived from istream, ostream, and iostream (respectively) with an assignment operator defined, allowing you to assign one stream to another. In most cases, you won’t be dealing with these classes directly.

Standard streams in C++

A standard stream is a pre-connected stream provided to a computer program by its environment. C++ comes with four predefined standard stream objects that have already been set up for your use. The first three, you have seen before:

  1. cin -- an istream_withassign class tied to the standard input (typically the keyboard)
  2. cout -- an ostream_withassign class tied to the standard output (typically the monitor)
  3. cerr -- an ostream_withassign class tied to the standard error (typically the monitor), providing unbuffered output
  4. clog -- an ostream_withassign class tied to the standard error (typically the monitor), providing buffered output

Unbuffered output is typically handled immediately, whereas buffered output is typically stored and written out as a block. Because clog isn’t used very often, it is often omitted from the list of standard streams.

In the next lesson, we’ll take a look at some more I/O related functionality in more detail.


23.2 -- Input with istream
Index
22.7 -- std::string inserting

110 comments to 23.1 — Input and output (I/O) streams

  • 不错不错真心谢谢博主。

  • 喜欢这个风格真心谢谢博主。by 答案兔https://www.daantu.com

  • Alek

    Hey ,look at the following snippet:
    int num{};
    std::cin >> num ;
    std::cout << num ;
    [/code]
    when the user enters a number to be stored in num. before it is even stored in num, it is  stored in a stream. and then istream buffer stores that data. and when "std::cout<<num" is executed it will somehow take that data from istream buffer and put it in its own and then sends it back to the stream. the data is always moved in all these processes right? and am I at all right about this process?
    and this stream which you defined previously is a particular part of memory whose sole task is reading and writing data and these sequential bytes are in OS ram not stack or something right ? I apologize if my questions seem to be stupid.
    thanks in advance!

    • Alek

      please take a look at my previous comment, also I'm so confused about stream and I/Ostream. here is what I think about it,please tell me if it's right or wrong.
      stream:is a sequence of bytes that only is responsible for holding datas.just like a stream of water, we can throw things into it(as cout insert data into it) or take things from it(as cin extracts data from it). so by IOstreams we mean two objects that are designed to work with that stream of water. am I right about this ?
      Thanks again.

      • nascardriver

        > when "std::cout<<num" is executed it will somehow take that data from istream buffer
        `std::cout` doesn't know about `std::cin` (It does, but only for synchronization). When you call `std::cout << num;`, `std::cout` doesn't care about where the value for `num` came from.

        You can compare a C++ stream to a video stream on the internet, it's pretty much the same thing. You can't have all the data at once, either because it's too much or simply doesn't exist yet (eg. live stream). The data comes in in small portions and can be consumed by the user. Once consumed, the data is gone from the stream (The data might stay, depends on the type of stream).

        You water stream example is also accurate to an extend. The water might not be stored in the stream, maybe there are people running around with buckets to and from a lake. Depending on the stream being input, output, or both, you can throw something into the stream or take something out.

        • Alek

          pardon ? Im afraid you haven't sent ur message successfully, its incomplete.

          • nascardriver

            I fixed my comment, thanks for letting me know I broke it :)

            • Alek

              thanks for your response then by C++ streams, we specifically mean I/O or other streams we are working with. I used to think that stream is considered a pool that has data and streams obj are used to extract or insert data to that pool.
              I just have another ambiguity here: "the insertion operator (<<) is used to put values in the stream. This also makes sense: you insert your values into the stream, and the data consumer (eg. monitor) uses them"
              then when we for example say ``std::cout<<"hello world"`` std::cout's buffer must be filled with characters of Hello World, why when I try to check how many characters are in the buffer I get 0 ? here is the code I've executed:

              • nascardriver

                `in_avail()` returns the number of characters ready for extraction. You can't extract anything from `std::cout` (It's an output stream, you can only write to it, not read).

                • Alek

                  then what did you mean that it puts the value in the stream,
                  if it doesn't mean that it is  placed in cout buffer or sth
                  .if rdbuf() and in_avail() don't have any meaning for std::cout why are they even defined for it though ?
                  but std::cout does have a buffer and with each cout those values are stored there?

                  • nascardriver

                    You can't access everything inside objects. `std::cout` doesn't let you access its buffer.

                    `rdbuf()` returns the same type (`std::basic_streambuf`) for input and output streams. `std::basic_streambuf` has functions for input and output. I suppose that is because streams need to read and write from/to their buffer no matter if they are input or output streams.

                    • Alek

                      thanks a bunch! there is also another thing about rdbuf(),I tested it a few times for some strings I get `1` when I call in_avail(),sometimes the right number of characters,and sometimes just 33 no matter how much more character I add into the string and extract it. if you don't get what I mean I can create a program like that again but I don't have it atm. have you seen something like this as well ? why does it behave this way ?

    • nascardriver

      `is_avail()` "returns the number of characters available in the get area", ie. however many character are available to be read without fetching more from some resource (eg. the terminal).
      It depends on the stream's implementation how many characters are available in a given situation.

  • Exiron47

    What is a buffer?

    • nascardriver

      A chunk of memory used to store something.

      When you copy a solution from your neighbor at school, you don't look at 1 character and write it down on your paper, then proceed with the next character.
      Instead, you read some of your neighbors words and store them in your brain. Then write down the words on your paper. That's a lot faster.
      Your brain is the buffer. Writing the words on your paper is flushing.

  • Exiron47

    How to flush the cout buffer?

  • koe

    "A standard stream is a pre-connected stream provided to a computer program by its environment. C++ comes with four predefined standard stream objects that have already been set up for your use."

    This confused me a bit, since it implies C++ plays some part in setting up the standard streams. Better might be:

    "A standard stream is a pre-connected stream provided to a computer program by its environment automatically. C++ comes with four objects defined in the <iostream> standard library that have been set up to use the standard streams."

  • Bram05

    Why shouldn't you use std::endl because it flushes the output stream, but it's okay to use std::cerr instead off std::clog?

    • nascardriver

      When an error is printed, you want it to be immediately visible in case the program crashes right after, which can happen, because an error occurred.
      Normal user messages aren't that important. We'd rather wait for the stream to choose a good time for flushing than waste performance printing the message immediately.

  • Vir1oN

    Hi

    I got super confused with the following:

    “Typically we deal with two different types of streams. Input streams are used to hold input from a data producer, such as a keyboard, a file, or a network. For example, the user may press a key on the keyboard while the program is currently not expecting any input. Rather than ignore the users keypress, the data is put into an input stream, where it will wait until the program is ready for it.

    Conversely, output streams are used to hold output for a particular data consumer, such as a monitor, a file, or a printer. When writing data to an output device, the device may not be ready to accept that data yet -- for example, the printer may still be warming up when the program writes data to its output stream. The data will sit in the output stream until the printer begins consuming it.”

    All the time before, I thought it was the buffer’s responsibility to do that type of things. So could you explain what is the difference between a buffer and a stream, and in which way they are related, please?

    • A buffer is a place where data is stored, usually without a specific type.
      A stream has a buffer in which it stores the data before sending it somewhere else.
      You might be able to access the buffer, eg. for `std::cout` via

  • Hi Alex!

    I modified to last example to follow your rules and fixed a typo (operatior)

    I don't think you need this example at all, since it doesn't show anything new.

  • sallyx

    nAge was not initialized. So, how you can rely on

    in case reading from input fails?

  • Viplav

    "Abstractly, a stream is just a sequence of characters that can be accessed sequentially."

    It'll probably be more correct to introduce streams as sequence of bytes rather than characters.

  • Shams

    Does the search bar in Google search is something like cin actually?

  • HS

    Hey I didn't find any specific definition of streams in the text, based on comments so far what I have formulated is:-
    A stream is just an abstraction to data transfer mechanism that is usually used to link to some source or sink that could potentially produce or consume infinite amounts of data in a sequential manner in the form of chunks that can be processed chunk by chunk.

  • Hardik

    Alex?
    It was written in a stackoverflow forum that the data/output int the buffer doesn't get sent to the OS until you write a newline or explicitly flush the buffer or a cin statement is encountered.
    But then,
    Why does

    work? There is no 'n' or endl or explicit flushing? And, even no cin statement is there !
    Is it something to do with the ';'?
    Waiting for your reply.....
    Thanks in Advance :)

  • Explain input and output library header file in C++.

  • Kausthub

    sir where can i find a tutoriol on stacks,queues and linked list on the site learncpp.com

    • Alex

      I haven't written them yet. They're still on my to-do list. I plan to tackle those after I finish rewriting the lessons on inheritance (and maybe template classes).

  • Prasenjit Saha

    If cin, cout are predefined objects of istream_withassign and ostream_withassign, then how does including iostream into the program works?

  • Matthieu B.

    "When you include the iostream header, you gain access to a whole heirarchy of classes responsible for providing I/O functionality (including one class that is actually named iostream). The class heirarchy for the non-file-I/O classes looks like this."

    "heirarchy" should be replaced with "hierarchy" in this paragraph (twice).

  • PV

    I cannot compile the example code with the exit(1); line in the if statement: "error: 'exit' was not declared in this scope". Why?
    I work with Code::Blocks 16.01 on W7 with GNU C++. Many thanks for your advice.

  • Nyap

    A standard stream is a pre-connected stream provided to a computer program by its environment. C++ comes with four predefined standard stream objects that have already been set up for your use.

    The first two, you have seen before

    actually, we've seen cerr aswell

  • Harshul

    Can you help me with this?
    http://stackoverflow.com/questions/37784797/c-noskipws-delays-end-of-file-detection-for-some-datatypes

Leave a Comment

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