What is the difference between cin and getline in C++?

  • Context: C/C++ 
  • Thread starter Thread starter JonnyG
  • Start date Start date
Click For Summary

Discussion Overview

The discussion revolves around the differences between the input methods `cin` and `getline` in C++, particularly in the context of handling user input for a recipe storage program. Participants explore the behavior of these methods when reading strings and the implications of whitespace and newline characters in the input buffer.

Discussion Character

  • Technical explanation
  • Debate/contested
  • Exploratory

Main Points Raised

  • One participant describes a problem where using `cin` to read a choice followed by `getline` to read a recipe name results in the program skipping the recipe input due to leftover newline characters in the input buffer.
  • Another participant suggests that the issue arises because `cin` reads up to the first whitespace, leaving the newline character in the buffer, which is then read by the subsequent `getline` call.
  • A different participant corrects the previous claim, stating that `cin` reads up to the first whitespace character, not a null character, and emphasizes that the newline character is what remains in the buffer.
  • Some participants discuss the behavior of `cin` in a loop, questioning how it handles whitespace and newline characters, and whether the presence of leftover whitespace affects subsequent reads.
  • One participant provides an example of a program that works without needing `cin.ignore()`, prompting questions about why this is the case given the previous explanations.

Areas of Agreement / Disagreement

Participants express differing views on the behavior of `cin` and `getline`, particularly regarding how whitespace and newline characters are handled in the input buffer. There is no consensus on the explanations provided, and multiple competing interpretations of the input behavior remain.

Contextual Notes

Some participants' explanations rely on assumptions about how input streams handle whitespace and newline characters, which may not be universally agreed upon. The discussion reflects varying levels of understanding and interpretation of C++ input behavior.

JonnyG
Messages
233
Reaction score
45
I am writing a small practice program to store and retrieve recipes using c++. I ran into a weird problem and I can't seem to figure out the cause of it. Check out this code:

Here is a source file:

[CODE lang="cpp" title="Recipes.cpp"]string getInitialChoice() {
string choice;
count << "Do you want to store a recipe or retrieve a recipe (s for store, r for retrieve)? " << endl;
cin >> choice;
return choice;
}

string getRecipeName() {
count << "Enter recipe name: ";
string recipeName;
getline(cin, recipeName);
return recipeName;
}[/CODE]Here is my main function:

[CODE lang="cpp" title="main.cpp"]int main() {
string choice = getInitialChoice();
if (choice == "s") {
getRecipeName();
}
}[/CODE]

When I run the program this is the output:

Do you want to store a recipe or retrieve a recipe (s for store, r for retrieve)? s
Enter recipe name: Press any key to continue . . .

Notice that it didn't give me any chance to enter the recipe name? It just reads in a blank space. I was able to fix this by going back to my function getInitialChoice() and changing the cin >> choice to getline(cin, choice), but I don't see why that should make a difference? The difference between cin and getline, as far as I know, is that cin will read up until it encounters a whitespace whereas getline will read up until it encounters a newline. Can someone please explain what's happening there?
 
Technology news on Phys.org
I hope I am right as I learn C++ not long ago and still learning here. I encountered this before, the reason is in the first cin, it read until the null character and stop. the null is still in the stream. The next cin will read the null that was left by the last one and just skip.

The way to fix it is put cin.ignore() before the next cin.
 
  • Like
Likes   Reactions: JonnyG
This works. Thank you.
 
yungman said:
I encountered this before, the reason is in the first cin, it read until the null character and stop. the null is still in the stream.
No, that isn't what happens at all. The stream input operator, >>, reads up to the first whitespace character, not the null character.
In the case of the program posted above, when the user is asked to choose an operation, typical responses would be s <ENTER> or r <ENTER>. It is the ENTER key that is still in the input buffer waiting for the next input operation. A call to cin.ignore() gets rid of that character.
 
  • Like
Likes   Reactions: Vanadium 50, yungman and JonnyG
Mark44 said:
No, that isn't what happens at all. The stream input operator, >>, reads up to the first whitespace character, not the null character.
In the case of the program posted above, when the user is asked to choose an operation, typical responses would be s <ENTER> or r <ENTER>. It is the ENTER key that is still in the input buffer waiting for the next input operation. A call to cin.ignore() gets rid of that character.
Yes, I was wrong, it's the space.
 
yungman said:
it's the space.
No, it's more likely the ENTER character, which is different from the space character. Both are kinds of whitespace, along with the tab character.
 
  • Like
Likes   Reactions: Vanadium 50
Mark44 said:
No, it's more likely the ENTER character, which is different from the space character. Both are kinds of whitespace, along with the tab character.

Suppose I have the code:

string in;
while (cin >> in) {
count << in;
}

Now suppose I first enter test1 <ENTER> . Then cin reads test1 then stops because it encounters the whitespace (<ENTER>). That whitespace is left in the buffer. Now on the next iteration of my while loop, suppose I enter test2 <ENTER> . After I hit the ENTER key, the buffer is holding: whitespace, test2, whitespace (the first whitespace being left over from the first iteration of my while loop). Since cin stops reading as soon as it encounters a whitespace, which in this case would be the first character in the buffer, how does cin read in test2? (I believe this code works, but from what I understood of your previous explanation, it shouldn't).
 
JonnyG said:
Suppose I have the code:

string in;
while (cin >> in) {
count << in;
}

Now suppose I first enter test1 <ENTER> . Then cin reads test1 then stops because it encounters the whitespace (<ENTER>). That whitespace is left in the buffer. Now on the next iteration of my while loop, suppose I enter test2 <ENTER> . After I hit the ENTER key, the buffer is holding: whitespace, test2, whitespace (the first whitespace being left over from the first iteration of my while loop). Since cin stops reading as soon as it encounters a whitespace, which in this case would be the first character in the buffer, how does cin read in test2? (I believe this code works, but from what I understood of your previous explanation, it shouldn't).
cin doesn't read anything, and count doesn't write anything. Both of these are just stream objects, input stream and output stream, respectively.
The actual reading is done by the extraction operator >> (extracting from a stream), and writing is done by the insertion operator << (inserting into a stream).
The extraction operator >> skips leading whitespace and reads subsequent characters until it hits a whitespace character. From the Visual Studio docs for this operator:
The operator skips the leading white spaces unless the skipws flag is set. It reads all the following characters until the next character is a white space or the end of the file is reached.
.

In the code above if you type abc <TAB>pdq<SPACE>xyz<ENTER>, the output line looks like this after three iterations of the loop:
abcpdqxyz

In the first input, in is abc. For some reason the first output writes it on the next line.
The next input skips the TAB character, and in becomes pdq, which is written following the first output.
The next input skips the SPACE character, and in become xyz, which gets written following the previous output.
The only thing that I don't quite understand is why the first output starts on a next line.
 
I just whipped up this little program, why this work? I can type name in the first two, and single character in the second two and works without cin.ignore().
C++:
#include <iostream>
using namespace std;

int main()
{    const int csize = 51;
    char Cr[csize]; char C;
    count << "Enter first line:  ";
    cin >> Cr; count << endl;
    count << " The first line is: " << Cr << endl;
    count << "Enter second line:  ";
    cin >> Cr; count << endl;
    count << " The second line is: " << Cr << endl;

    count << "Enter first letter:  ";
    cin >> C; count << endl;
    count << " The first char is: " << C << endl;
    count << "Enter second char:  ";
    cin >> C; count << endl;
    count << " The second char is: " << C << endl;
    return 0;
}
 

Similar threads

  • · Replies 118 ·
4
Replies
118
Views
10K
  • · Replies 41 ·
2
Replies
41
Views
5K
  • · Replies 4 ·
Replies
4
Views
6K
  • · Replies 4 ·
Replies
4
Views
5K
Replies
2
Views
2K
  • · Replies 65 ·
3
Replies
65
Views
8K
Replies
4
Views
3K
  • · Replies 3 ·
Replies
3
Views
4K
  • · Replies 8 ·
Replies
8
Views
2K
  • · Replies 5 ·
Replies
5
Views
5K