Problem of using cin twice - c++

Here is the code:
string str;
cin>>str;
cout<<"first input:"<<str<<endl;
getline(cin, str);
cout<<"line input:"<<str<<endl;
The result is that getline never pauses for user input, therefore the second output is always empty.
After spending some time on it, I realized after the first call "cin>>str", it seems '\n' is still stored in cin (using cin.peek() to check), which ends getline immediately. The solution will be adding one more line between the first usage and the second one:
cin.ignore(numeric_limits::max(), '\n');
However, I still don't understand, why is '\n' left there after the first call? What does istream& operator>> really do?

The \n is left in the input stream as per the way operator>> is defined for std::string. The std::string is filled with characters from the input stream until a whitespace character is found (in this case \n), at which point the filling stops and the whitespace is now the next character in the input stream.
You can also remove the \n by calling cin.get() immediately after cin>>str. There are many, many different ways of skinning this particular I/O cat, however. (Perhaps a good question in and of itself?)

By default, the stream insertion operator reads until it sees whitespace. Your first call isn't returning until it sees a space, tab, newline, etc. Then the next character needs to be consumed so that you can get to the next one.

I generally recommend only doing line-oriented input from std::cin. So, your code could look something like this:
string str;
int val;
// Read an entire line and parse an integer from it
{
string line;
getline(cin, line);
istringstream iss(line);
iss >> val;
}
cout<<"first input:"<<val<<endl;
getline(cin, str);
cout<<"line input:"<<str<<endl;
Be sure to add error checking too.
The getline-only approach avoids having to think about line buffering of the input, of clearing the input, etc. If you directly read something with >>, the input does not terminate if the user hits enter instead of inputting what is required, but instead continues until a token is input (this behavior is usually not wanted).

As others have said, th problem is that the newline is left from the first extraction. One solution I do is to discard all the left characters in the stream:
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );

Good writeup that explains some of the reasons why you are running into this issue, primarily due to the behavior of the input types and that you are mixing them

Also was searching for most suitable solution. Implementation of this operator could produce problems. And not always is acceptable to read entire line, or not mix different types in one input line.
To solve problem, when you want to read some data from cin, and don't know if whitespaces was correctly extracted after last input operation, you can do like this:
std::string str;
std::cin >> std::ws >> str;
But you can't use this to clear trailing newline symbol after last input operation from cin to do not affect new input, because std::ws will consume all whitespaces and will not return control until first non-ws character or EOF will be found, so pressing enter will not finish input process.
In this case should be used
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
which is more flexible.
P.S. If got errors with max() function such as "identifier expected", it could be caused by max macros defined in some header (for example, by Microsoft); this could be fixed by using
#undef max

Related

How to ignore line break after reading two ints with cin?

I am new to C++, I have practically started it today. Any way, I am facing a problem where the first line contains two integers, and the next lines contain operations to be done. It's a fairly weird problem, actually, so I won't go into the details. Well, I am having a problem with reading the first line, and then the follow up operations.
My code looks like this so far:
int m, j;
string comando;
string OPR
cin << m << l;
while (getline(cin, comando)) {
OPR = comando.substr(0, 3);
}
The problem is: Apparently, whenever I write both m and l in the same line, the \n stays in the buffer, and it get's read by the newline, causing a problem when I try to take the substring. I tried adding a char variable that would be read after m and l, which would, supposedly, get the \n. However, it is getting the first letter of the newline instead, which, then, messes up my code. I tried to see if I had any syntax errors or anything, but that isn't it. I also looked for ways to ignore the \n char, but everything I found was related to strings, or reading from files.
I know I could read the line, and then cast the two ints from string to int, but that seems like a bad way to do it (at least it would be a bad way to do it in C).
Anyways, if any one can help me, that would be awesome, thanks!
P.S.: I don't do a check before the substr operation because, by the definition of the problem, the line will have a 3-char operation, a space and then an integer.
A good place to look for tips for common problems like this is your favorite reference:
When used immediately after whitespace-delimited input, e.g. after int n; std::cin >> n;, getline consumes the endline character left on the input stream by operator>>, and returns immediately. A common solution is to ignore all leftover characters on the line of input with cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); before switching to line-oriented input.
From here.

How do I start taking getline only after inputting a variable and not immediately?

int t;
cin>>t;
while(t--){
string s;
getline(cin,s);
cout<<s.length()<<endl;
}
When I run the program after inputting t it immediately prints 0 when I press enter after input t.
Rather what I want to have is take t then start getline inputs.
Put cin.ignore before the loop and try again.
If there is a newline left in the stream, it will stop reading there.
The most robust advice is to never mix formatted I/O (e.g. using operator >>) with line oriented input on the same stream (e.g. getline()) or with character oriented input (e.g. cin.get()).
The reason is that the different styles of input function respond to newlines differently. Formatted I/O tends to stop and leave a newline in the stream (where it will be encountered first up by getline() in your code) whereas line oriented input will tend to respond immediately to any newline and discard it.
So change cin >> t to
string temp_string;
getline(cin, some_string);
istringstream some_stream(some_string); // from <sstream>
some_stream >> t;
The above can be placed in a separate function if you find yourself doing such things frequently.
When combined with the code in your loop, this will only ever interact directly with cin using line-oriented input, which will avoid the sort of confusion you are seeing.
Using tricks like cin.ignore() or stream manipulators (e.g. getline(cin << std::ws, s) will be fragile, depending on how other code (before or after yours) interacts with the stream.

Why does cin command leaves a '\n' in the buffer?

This is related to: cin and getline skipping input But they don't answer the why it happens just the how to fix it.
Why does cin leaves a '\n' in the buffer but just cin.getline takes it?
for example:
cin >> foo;
cin >> bar;//No problem
cin >> baz;//No problem.
But with cin.getline
cin >> foo;
cin.getline(bar,100);//will take the '\n'
So why it doesn't happen with cin but it does with cin.getline?
Because, when you say getline you say you want to get a line... A line is string that ends with \n, the ending is integral part of it.
When you say cin >> something, you want to get precisely something, nothing more. End-line marker is not part of it, so it's not consumed. Unless you would have a special type for line, but there is no such thing in standard library.
While without citations from standard this might be taken as opinion, but this is logic behind it. They have different semantics. There is also another difference getline works as unformatted input, and operator>> works as formatted input. I strongly suggest reading of those links to get the differences. This also says that they are semantically different.
Another answer, better or not is debatable, would be to quote standard, that I am sure says, how getline behaves, and how operator>> behaves for different types, and say, it works like this, because standard says so. This would be good, because the standard absolutely defines how things work and it can do so arbitrarily... And it rarely does explain motivation and logic behind the design.
You are not comparing cin to cin.getline, but rather cin.operator>> and cin.getline, and that is exactly what these functions are defined to do. The answer to the question "why" is "by definition". If you want rationale, I can't give it to you.
cin.getline reads and consumes until a newline \n is entered. cin.operator>> does not consume this newline. The latter performs formatted input, skipping leading whitespace, until the end of the object it was reading (in your case whatever foo is) "stops" (in case foo is an int, when the character isn't a number). A newline is what remains when the number is consumed from the input line. cin.getline reads a line, and consumes the newline by definition.
Make sure to always check for error on each stream operation:
if(cin >> foo)
or
if(std::getline(cin, some_string))
Note I used std::getline instead of the stream's member because this way there's no need for any magic numbers (the 100 in your code).

incorrect results with gets () due to the stray \n in istream BUT not with scanf() or cin?

In the program printed below the problem with gets () is that it takes the data for the first time only, and every subsequent call results in a null, due to the stray \n in the istream left while entering the number.
main()
{
char name[20];
int number;
for(int i=0;i<5;i++)
{
printf("enter name");
gets(s);
printf("enter phone number");
cin>>a;
}
}
Now my question is that why isn't the same happening for when I use scanf() or cin ? I mean whats the difference in the way cin and gets() takes their values which enables cin (and scanf ) to successfully leave that stray \n but not gets() ?
PS: I know about fgets(), and that gets() is deprecated and its ill-effects, and generally dont use it as well.
You're mixing line-oriented input with field-oriented input. Functions like gets(), fgets(), etc read lines. They don't care necessarily the contents of the line, but they'll read the whole line (provided there's space for it in some cases).
Field oriented inputs like cin's >> operator and scanf() don't care about lines, they care about fields. A call like scanf("%d %d %d", &x, &y, &z); doesn't care if they're on the same line or 3 separate lines (or even if you leave blank lines).
These field oriented input functions tend to leave behind newline characters that will confuse line oriented input functions. In general, you should avoid mixing the two, If you want to do both, it's often useful to read the line then use sscanf() or stringstream to do field based input from it. This also makes recovering from bad inputs a bit easier, and you won't have to worry about whether or not there are extra '\n' chars waiting for your next input function.
scanf and cin >> both read fields delimeted by whitespace, and ignore leading whitespace. Now whitepsace is spaces, tabs, AND NEWLINES, so extra newlines in the input doesn't bother them. More importantly, after reading something, they DO NOT read any of the following whitespace, instead leaving it on the input for the next call to read.
Now with scanf, you can tell it explicitly to read (and throw away) as much whitespace as it can by using a space at the end of the format string, but that will work poorly for interactive input, as it will KEEP trying to read until it gets some non-whitepsace. so if you change the end of your loop to:
printf("enter phone number");
scanf("%d ", &a);
it will seem to hang after entering the phone number, as its waiting for you to enter some non-whitespace, which will ultimately be read by the next loop iteration as the next name.
You CAN use scanf to do what you want -- read and consume the text following the phone number up to the newline -- but its not pretty:
scanf("%d%*[^\n]", &a); scanf("%*1[\n]");
You actually need two scanf calls to consume the newline as well as any space or other cruft that might be on the line.
gets(), unlike fgets(), should replace a terminating newline with a null character.
This is from gets() man page:
The gets() function shall read bytes from the standard input stream, stdin, into the array pointed to by s, until a is read or an end-of-file condition is encountered. Any shall be discarded and a null byte shall be placed immediately after the last byte read into the array."
Though fgets() will pass the newline unchanged:
The fgets() function shall read bytes from stream into the array pointed to by s, until n-1 bytes are read, or a is read and transferred to s, or an end-of-file condition is encountered. The string is then terminated with a null byte.
So, seems that your implementation is unconforming... Mine works as stated.

Why doesn't whitespace act as a delimiter when printing strings with ostream operator<<?

I know that when writing code like std::cin >> some_var; , where some_var is a string variable, only the first word that was inputted will be stored in some_var. But I do not understand why std::cout << "something here"; does not only output "something". Am I missing something?
When reading input using cin >> some_var, the delimiter is space by default (you can change this though), while when printing, cout prints till its find \0 which is end of the string.
If you want to read till it finds \0 in the input stream, then you've to write this:
std::getline(std::cin, some_var, '\0');
You can give any other character as delimiter as third argument of std::getline function.
Note that there is a member function with same name getline which is slightly different than the one I used above which is a free standalone function.
Compare:
std::getline - free standalone function. An overloaded function is also available.
istream::getline - member function of std::istream
I used the first one.
It was deemed useful that cin, when reading into a string terminates at whitespace. But it wasn't deemed useful that only the first word is printed when you print a string.
After all you said print "something here" to cout· In the other case, you just said read something from cin. The choice between a word, between a line and between the whole content of stdin (until an EOF is received) is arbitrary and the design happens to be to read a word. That makes it easy to quickly read a record line like "john 10 2.15" (first read into string, then into an int, and then into a float). Use std::getline to read a whole line into a string.
Because when you take input from std::cin, it needs to know when to stop taking input. If it didn't stop at the first word, when would it stop? However, when you output a variable, the answer is easy- you output that one variable.
Yes... cin stops at a space because, by default, it thinks you want a word. cout doesn't follow the same restriction, because, well, why would it? Think about it for a second — would it make any sense whatsoever if printing out "Hello, world!" actually just printed out "Hello,"? Of course it doesn't make any sense. The developer knows what they want to output (at least, we hope :D).
I think they took a convention and stick to it. In the case of <<, it is clear that you specify what to be written. In the case of a >>, they have to decide where to stop. Newline? Maybe this is the most natural alternative, but they just decided to stop reading at a space.
The delimiters are different for cin and for cout. For cin, input is split at whitespaces, for cout, at end of lines. You can change those default delimiters though.