problems with concatenating cout and cin.get()..

Pages: 12
Hi all, I am new to C++ and I wrote a test program to print out characters that are left in the input-stream when cin encountered inappropriate input, however I encountered some strange phenomena when I tried to concatenate cout with cin.get(). I am not sure if this is a conventional way to do this but here's the essential part of my code that has this issue:

1
2
3
4
5
6
7
#include <iostream>
int main()
{
using namespace std;
cout<<(char)cin.get()<<(char)cin.get()<<(char)cin.get()<<endl;
return 0;
}



The problem is when I run the executable and input:

abc<Enter>


the actual content get printed out is:

cba


It seems that the order of the characters that are passed to the output-stream is reversed...

Another problem is I read somewhere that calling cin to build a new input-stream will cause the current output-stream to be flushed. However for the above code if I input:

a<Enter>


The program will continue to wait for additional input without printing out the character 'a' and '\n' that I have already inputed...
Any help on this will be appreciated...Thanks!
Last edited on
eeek sscratch what i said, maybe the concatenated calls are read in order fromr ight to left?
Last edited on
cin.get() returns the int-type-casted character that it gets from the input stream, the one that returns a reference to an stream object is an overloaded version of get(char&) as in cin.get(char&)...so there should not be any problems with this...the code can pass through compilation without errors or warnings
It seems that the elements in the chain simply get evaluated from right to left.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>

char printa()
{
	std::cerr << "Message";
	return 'a';
}

char printb()
{
	std::cerr << " is ";
	return 'b';
}

char printc()
{
	std::cerr << "nothing special." << std::endl;
	return 'c';
}

int main()
{
	std::cout << printc() << printb() << printa();
}
Message is nothing special.
cba
You are playing with side-effects. There is no guarantee that the cin.get() on the left will be called before the cin.get() on the right, or any other order.

Get your stuff first, then print it.

Hope this helps.
I think it is undefined behaviour.
Similar to x = ++x;, the compiler can choose the order of evaluation of the sub-expressions.
I don't think it is undefined behaviour. Only the order in which to call cin.get() is undefined.
¿How do you call it, then?
What?

If I was doing something like this I would probably use a loop.
1
2
3
4
5
for (int i = 0; i < 3; i++)
{
	cout << (char) cin.get();
}
cout << endl;
I don't think this is undefined either.

http://en.cppreference.com/w/cpp/language/operator_precedence
This states that the bit-shift operator is done left-to-right.

I believe the cout<<(char)cin.get() calls an overloaded function (ostream object member) with a header like this:
ostream& operator << (char);

This means that the left-most cin.get() is called first, then the second, then third. *this is returned so that the cout can be chained.

The cout part of the code is working as expected and is completely defined. So now... the interesting part is what cin.get() does. See:
http://cplusplus.com/reference/iostream/istream/get/

This tells us that the get() function returns an int value (which we have casted to a char) and extracts a character. The question now is: which character? It appears that it is extracting the last character in the stream and returns its value. You were expecting it to extract the first (oldest) character in the sequence. I don't see this as being defined on cplusplus.com, but I am sure it is defined somewhere.
Last edited on
No, I mean if it is not "undefined behaviour" how do you call it.
@ne555 - Sorry, I still not understand your question.

@Stewbond - precedence has nothing to do with this.
Last edited on
I don't think this is undefined either.


It is undefined because you are modifying cin multiple times (using get) in between sequence points.

If you do something like this:

a = arg() + abc() + d();

The compiler is free to perform abc(), then d(), then arg() if it feels like it.

@ne555 - Sorry, I still not understand your question.


He means that since it is *not* undefined, it must be defined. So he wants to know what it is defined as.
Thanks guys, I think this is a sequence point issue. The right-most cin.get() get called first and extracts the first character in the input-stream while the left-most cin.get() get called last and extracts the last character in the input-stream. However cout still prints from left to right which means it prints the return value of the first cin.get() that end up getting the last character in the input-stream. Thanks again for all the helpful comments.
Just note that the compiler can call the cin.get()s in any order it feels like.
cout<<(char)cin.get()<<(char)cin.get()<<(char)cin.get()<<endl;
Didn't even know that was legal C++ :o.
Didn't even know that was legal C++ :o.

I, too, wish C++ was illegal.
> It is undefined because you are modifying cin multiple times (using get) in between sequence points.

> Thanks guys, I think this is a sequence point issue.

C++ does not have the concept of sequence points.

The three calls to std::cin.get() are indeterminately sequenced - ie. they may be sequenced in any order, but the three evaluations cannot overlap of interleave.

I, too, wish C++ was illegal.

If C++ was illegal then C would be illegal too. Since C is a subset of C++ making one illegal would mean the other one would have to be illegal too as you couldn't have C++ without C. ;) I meant I didn't know you could have cin.get() in the same line as cout.
Last edited on by closed account z6A9GNh0
Then you've got a conceptual error.
You evaluate cin.get() and obtain and integer, so you are just printing a number ¿why wouldn't be allowed?
Pages: 12