Concepts / Output Operations and Chaining in C++

Output Operations and Chaining in C++

A single statement such as cin >> i >> d; reads several values in order, with each >> filling the variable on its right.

  • Programming

One Statement, Two Values

A single statement can read more than one value from the keyboard. The statement cin >> i >> d; reads two values in order, and each >> operator fills the variable on its right. In this statement, i is an int and d is a double. The question this article answers is simple to state: how does one statement with two >> operators decide which input goes where?

What do you think happens?

If the keyboard delivers the input 42 7 and the program runs cin >> i >> d;, what does i hold and what does d hold?

  • i holds 7 and d holds 42

  • i holds 42 and d holds 7

  • i holds 42 and d holds 42

  • Both variables stay unchanged

Reveal answer
Answer:

i holds 42 and d holds 7

The chain reads from left to right. The first >> fills i with the first value, 42, and the second >> fills d with the next value, 7. Spaces between values are skipped, so they do not become part of either value.

Keep the guess you just made in mind. The rest of this article traces the read step by step, so you can check whether your expectation about the order of the values was right.

Tracing the Read Cursor Through cin >> i >> d

Think of the input as a stream of characters with a read cursor that moves forward. The chain reads from left to right, and each read begins where the previous read stopped. The first >> starts at the beginning of the input, extracts a value for i, and leaves the cursor just past that value. The second >> then starts from that position, not from the beginning again.

42first tokeni (int)holds 427second tokend (double)holds 7first >>second >>
Which token in the input goes into i, and which goes into d, after cin >> i >> d runs with the input 42 7?
Keyboard input42 then 7iintddouble1: read 42 into i2: read 7 into d
In what order do the extractions happen, and which variable does each one fill?

Skipping Whitespace Between Values

By default, >> skips initial whitespace before it reads a value. This is why spaces between values do not become part of them. Whether the input is written as 42 7, as 42 7, or with the values on separate lines, each >> first moves past the whitespace and then reads the next value.

cpp
Output
Input: 42 7
i = 42
d = 7
Notes on the code
  • std::cin >> i >> d; is one statement with two extractions, applied in order
  • The first >> fills i, the second >> fills d
  • Spaces between 42 and 7 are skipped and are not stored in either variable

Where an Integer Read Stops

An integer read keeps going only while the characters are digits. It is terminated by any character that is not a digit, so a period or a letter ends it. The character that ends the read is not consumed as part of the integer. It stays in the stream, and the next >> starts from that character.

42x7input stream42stored in i7still unreadxnot a digitdigits 4 and 2stops at xnext read must start at x
After reading an int from the input 42x7, what remains in the stream, and where does the next read start?

The same rule applies to a decimal point. In an input such as 3.5 for an int, the integer read ends at the period, so the period is the first character left for the next operator to examine. Reading the period as a digit is not something an integer extraction does, which is why the position where an integer read ended is the key to predicting what the next value will be.

Tracing a Chained Read Step by Step

Worked example

Reading three tokens with two extractions

The input is 42 7 abc, and the program runs cin >> i >> d; with i an int and d a double. What does each variable hold, and what is left in the stream?

  1. 1
    Start of the input

    The cursor is at the beginning of 42 7 abc. The first >> skips any leading whitespace, and there is none here.

  2. 2
    First >> reads an int

    The integer read collects 4 and 2 and stops at the space, which is not a digit. i becomes 42 and the cursor sits at the space.

  3. 3
    Second >> skips whitespace and reads a double

    The second >> begins at the space from the previous step, skips it, and reads 7. d becomes 7 and the cursor sits at the space before abc.

  4. 4
    What remains

    The text abc is not read by this statement. It stays in the stream for any later read.

Result

i holds 42, d holds 7, and abc remains unread in the stream.

Startbefore 42After first >>i = 42After second >>d = 7first >> reads 42second >> reads 7
At each >> in the chain for input 42 7 abc, where does the read cursor sit and what value is stored?

Finding Where a Result Diverges

When a chained read gives an unexpected value, the useful question is which >> operator produced it. Each operator in the chain has one job: it skips whitespace, reads one value, and leaves the stream positioned for the next operator. Work backward from the variable that looks wrong.

Debugging

Suppose the first variable is correct but the second is wrong. Then the first read worked, and the problem lies in what the second read found after the first one stopped. Look at the characters that remained after the first integer ended. If the first variable is already wrong, look at the start of the input and at the first run of digits, because that is where the first read began.

First variableis it correct?Start of inputcheck first digit runCharacters afterfirst valuecheck what the second readfoundnoyes
When the first variable is right and the second is wrong, which part of the input should you inspect first?

Mistakes Beginners Make With Chained Reads

  • Common mistake

    Assuming the second value is read from the start of the input

    What it looks like

    After cin >> i >> d; with input 42 7, expecting d to read 42 again.

    Why it fails

    Each >> begins where the previous read stopped, so the chain moves forward through the input.

    Do this instead

    Trace the cursor forward: the first read consumes 42, and the second read starts after it.

  • Common mistake

    Expecting a digit-run to include a following letter or period

    What it looks like

    Reading 42x7 into an int and expecting i to hold 427.

    Why it fails

    An integer read is terminated by any character that is not a digit, so the x ends the read.

    Do this instead

    Read digits up to the first non-digit only, and leave the terminating character in the stream.

  • Common mistake

    Thinking spaces between values become part of the values

    What it looks like

    Believing the input 42 7 gives i a value containing a space.

    Why it fails

    By default >> skips initial whitespace, so spaces between values are not stored.

    Do this instead

    Treat whitespace as a separator that each >> skips before reading.

  • Common mistake

    Forgetting that unread characters remain in the stream for later reads

Practice: Predicting the Split

MEDIUM

The program declares int i; and double d; and runs cin >> i >> d; The keyboard delivers the input 15 2.5 extra. Before you check, predict the value of i and the value of d, and say where the read cursor sits after the statement finishes.

Hints
  • Trace the first >> from the start of the input, stopping at the first character that is not a digit.
  • The second >> begins at the character where the first read stopped.
  • The text extra is never read by this statement.

Key Takeaways

  • A statement such as cin >> i >> d; reads several values in order, with each >> filling the variable on its right.
  • The chain reads from left to right, and each read begins where the previous read stopped.
  • An integer read is terminated by any character that is not a digit, such as a period or a letter, and that character stays in the stream.
  • By default >> skips initial whitespace, so spaces between values do not become part of the values.
  • When a result is wrong, identify which >> produced it: a wrong first variable points to the start of the input, while a wrong second variable points to what remained after the first read.

More concepts starting with O