C instruction is being reordered when cin cout and gets is used consecutively

779 Views Asked by At

Does anyone knows why C instruction is being reordered when cin cout and gets is used consecutively here? I am using Dev-C++ 4.9.9.2.

#include<iostream>
using namespace std;

int main(){
    char a[10],b;
    for(;;){
        cout<<"\ncin>>b:";
        cin>>b;
        cout<<"gets(a):";
        gets(a);
        cout<<"cout<<a<<b:"<<a<<" "<<b<<"\n\n";
    }
}

I got an output like:

cin>>b:132
gets(a):cout<<a<<b:32 1


cin>>b:465
gets(a):cout<<a<<b:65 4


cin>>b:312242
gets(a):cout<<a<<b:12242 3


cin>>b:1
gets(a):cout<<a<<b: 1

cin>>b:

It seemed like some input for cin was passed in gets.. and it also appears that instructions were reordered like:

cin>>b;
gets(a);
cout<<"gets(a):";

instead of,

cin>>b;
cout<<"gets(a):";
gets(a);
4

There are 4 best solutions below

2
On BEST ANSWER

cin>>b read just a character, leaving the rest of the input to be read by later input operation. So gets sill has something to read and don't block.

At the first cin >> b, there is no input available. You enter '132\n' (input from terminal is usually made line by line) in a buffer and just get the 1 out of it. gets reads the next characters 32 and the \n which terminates gets. It doesn't need to read something more from the terminal.

0
On

Nothing has been re-ordered.

your input from keyboard has been send only when you pressed enter. At that time, there have been enough data to execute the cin<<b, the following cout, then to complete the gets(a).

In others words, the execution of cin<<b is suspended to the reception of a char. But that char is not send to the program until you pressed 'Enter' (this is because of your terminal settings). When you press 'Enter', the first char is received by cin<<b and the remaining is buffered. cout executes, and when it is the turn of gets(a), the buffer delivers the remaining chars included the carriage return, so gets(a) completes as well, with the data you entered to complete the cin<<b instruction.

Try to simply press enter for the cin<<b to complete, then you'll see the cout, and then you will have the gets(a) waiting for your inputs.

0
On

While not really answering your question...

The idiomatic way in C++ would rather be to use getline. It's an accident of history that does not make it part of the iostream interface directly, but it really is the function to use for inputs.

Shameless plug from the website:

// getline with strings
#include <iostream>
#include <string>

int main () {
  std::string str;
  std::cout << "Please enter full name: ";
  getline (std::cin,str);
  std::cout << "Thank you, " << str << ".\n";
}

The main advantage of getline, in this version, is that it reads up until it encounters a line-ending character.

You can specify your own set of "line-ending" characters in the overload accepting a third parameter, to make it stop on commas or colons, for example.

0
On

The code isn't reordered, but std::cout is buffered so the string doesn't appear immediately on your display. Therefore gets(a) will be executed with the output still in the buffer.

You can add a <<flush after the output string to make cout flush it's buffer.

When you use std::cin, it knows how to tell std::cout to flush the buffer before the input starts, so you don't have to.