0

Let's take an input : 10 20 30 40 50
I want the output to print exactly as the input but the following code prints only 10 as output.

#include<iostream>
int main() {

    std::cout << " Please enter sequence of numbers separated by space"
              << " then press enter : ";

    int numbers;
    std::cin>>numbers;
    std::cout << numbers <<' ';
}

The reason I think is that the input operator '>>' takes 10 as input and leaves space in the input stream. For the next input, cin finds whitespace and concludes that the input has ended. Hence, 10 as output.

Now If I input using a while loop the code prints exactly what I want it to.

 int numbers;
 while(std::cin >> numbers)

 std::cout << numbers <<' '; 

OUTPUT : 10 20 30 40 50

Why does the input work fine using a while loop? Please explain what exactly is happening.

mediocrevegetable1
  • 4,086
  • 1
  • 11
  • 33
  • 1
    Please explain in your own words how the second snippet work. There seems to be a fundamental misunderstanding of what a `while` loop is. – Bob__ May 03 '21 at 06:40
  • `Why the input works fine using a while loop?` because `std::cin` reads a single input and doesn't loop again. And even if it loops then how can it know to call `std::cout` in each loop to print all the inputs? – phuclv May 03 '21 at 06:41
  • "*Why the input works fine using a while loop?*" - Your 1st code reads only 1 input value and then prints out only that value. The rest of the input is not read at all. Your 2nd code reads input values in a loop and prints out each value that is read. What is not to understand about that? Do you understand what a loop even is? – Remy Lebeau May 03 '21 at 06:41
  • 1
    you really need to read a good book: [The Definitive C++ Book Guide and List](https://stackoverflow.com/q/388242/995714). And it's a must to read the documentation of each function you call before using: [std::cout](https://en.cppreference.com/w/cpp/io/cout) and [std::cin](https://en.cppreference.com/w/cpp/io/cin) – phuclv May 03 '21 at 06:43
  • @phuclv "*because `std::cin` reads a single input*" - more accurately, it is `operator>>` that is reading a single input value from `std::cin`. – Remy Lebeau May 03 '21 at 06:45
  • @Bob__ I don't know how the second snippet works that's why I asked here. So what a while loop does is it checks a condition and returns a boolean value . If the condition is true the loop executes and when the condition is false the loop terminates. – Ritwiz Prasher May 03 '21 at 14:16
  • @phuclv Yes I'm using C++ Primer (5th edition). To give more context I encountered this problem yesterday and I was going through the book today (chapter 3 vector operations) where the code snippet uses a while statement to input grades. So thats why I used a while loop . – Ritwiz Prasher May 03 '21 at 14:25
  • 1
    Read the documentation of your C++ compiler (e.g. [GCC](http://gcc.gnu.org/) ...) and of your debugger (e.g. [GDB](https://www.gnu.org/software/gdb/)). See also [this C++ reference](https://en.cppreference.com/w/cpp). Take inspiration from existing open source C++ software (like [FLTK](http://fltk.org/), [fish](https://fishshell.com/), [ninja](http://ninja-build.org/), [Clang](https://clang.llvm.org/)...). If allowed, use the [Clang static analyzer](https://clang-analyzer.llvm.org/) – Basile Starynkevitch May 04 '21 at 05:30

4 Answers4

2

You're pretty much correct about what's happening in the first example. You enter 10 20 30 40 into stdin, but it only takes the first number, 10, as input and stores it into numbers. The rest is left stuck in stdin and the program exits.

With proper indentation, I believe your code in the second example will be far clearer.

#include <iostream>

int main()
{
    int n = 0;
    while (std::cin >> n)
        std::cout << n << ' ';
}

Basically, this program works in a pretty weird way. In the first run of the while loop, let's say you input 1 2 3. Visualizing it, stdin would look like this:

1 2 3

Now, it has to take a number from this. So it takes 1 and then finds a space, so it stops. Now that 1 is in n, it prints 1 followed by a space. After the first run of the loop, stdin looks like this:

2 3

In the second run of the loop, it doesn't actually prompt you for more input because stdin is not empty. So it'll just take input from what's already there. It sees 2 at the beginning, takes that and stops at the next space, and puts it into n. n is then printed, followed by a space. stdin now looks like this:

3

Same thing happens with 3. It takes 3 and puts it into n which is printed, and this time stdin has been cleared. After this, std::cin takes no more input and returns false in the last check of the loop as it has hit eof. So to hopefully make things a bit clearer, after unrolling the loop, your program looks like this:

#include <iostream>

int main()
{
    int n = 0;
    std::cin >> n;         // Here you input "1 2 3", 1 is taken leaving "2 3" in stdin
    std::cout << n << ' '; // "1 " printed
    std::cin >> n;         // 2 is taken from stdin, leaving "3"
    std::cout << n << ' '; // "2 " printed
    std::cin >> n;         // 3 is taken from stdin, nothing left
    std::cout << n << ' '; // "3 " printed
}
mediocrevegetable1
  • 4,086
  • 1
  • 11
  • 33
0

Actually when you input 10 20 30 40 50 . It only gets 10 because it ignore all the values after space. If you get all the values try Array and used these values in further calculations and print these values using for and while loops.

Abdullah Sheikh
  • 243
  • 1
  • 16
0

you can loop every digit you want to type with this function:

std::string spaceAfterDigit(int len)
{
    std::string digits[256];
    std::string result;
    std::cout << "Type digits but after every digit press enter: ";
    for (int i = 0; i < len; i++)
    {
        std::cin >> digits[i];
        std::cout << " ";
        result += digits[i] + " ";
    }

    return result;
}

And if you want to convert string to int just use stringstream:

stringstream ss;  
ss << result;  
ss >> resultInt;
coderx64
  • 185
  • 1
  • 11
0

In the following I'll show what output C++ Insights produces from the source code of the second posted snippet (see e.g. here, indentation mine):

#include<iostream>

int main()
{
  std::operator<<(
    std::operator<<(
      std::cout, 
      " Please enter sequence of numbers separated by space"
    ), 
    " then press enter : "
  );

  int numbers;
  while ( static_cast<bool>(
            static_cast<const std::basic_ios<char>&>(
              std::cin.operator>>(numbers)
            ).operator bool()
          ) )
  {
    std::operator<<(std::cout.operator<<(numbers), ' ');
  }
  
}

There seems to be a lot of things going on, so let's get the gist of it.

  • Despite the unfortunate indentation choices, OP's snippet is equivalent to:

    int numbers;
    while ( std::cin >> numbers )
    {
        std::cout << numbers <<' '; 
    }
    

    This is a simple while loop, where the condition, evaluated at each iteration is std::cin >> number (more on this, later) and the body, repeated as long as the condition evaluates true, is std::cout << numbers << ' ';. So, this is a loop that repeatedly extracts a (single) number from the input stream and puts it into the output stream (along with a space character).

  • Now let's take a closer look to that condition.

    std::cin >> number is actually a call to the member function operator>>(int &) of std::cin, which

    Extracts an integer value potentially skipping preceding whitespace. The value is stored to a given reference value. [...]
    Return value: *this.

    So it not only extracts the value from the input stream, but it also returns a reference to std::cin. This is useful, because we can use the return value to concatenate operations on this object.

  • Another important member function of std::cin is operator bool, which

    Checks whether the stream has no errors. [...]
    Returns true if the stream has no errors and is ready for I/O operations. Specifically, returns !fail().
    This operator makes it possible to use streams and functions that return references to streams as loop conditions, resulting in the idiomatic C++ input loops such as while(stream >> value) {...} or while(getline(stream, string)){...}. Such loops execute the loop's body only if the input operation succeeded.

Bob__
  • 12,361
  • 3
  • 28
  • 42