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

  • Thread starter JonnyG
  • Start date
In summary, this conversation discusses a problem encountered while writing a practice program to store and retrieve recipes using c++. The issue was that the program would not prompt for recipe names after selecting the "store" option. This was solved by using the getline() function instead of the cin operator. The conversation also delves into the difference between cin and getline, and how cin reads up to the first whitespace character while getline reads up to the end of the line. The conversation ends with a discussion on the behavior of cin and cout and how they are not responsible for reading and writing, but rather the extraction and insertion operators are.
  • #1
JonnyG
233
30
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:

Recipes.cpp:
string getInitialChoice() {
    string choice;
    cout << "Do you want to store a recipe or retrieve a recipe (s for store, r for retrieve)? " << endl;
    cin >> choice;
    return choice;
}

string getRecipeName() {
    cout << "Enter recipe name: ";
    string recipeName;
    getline(cin, recipeName);
    return recipeName;
}
Here is my main function:

main.cpp:
int main() {
    string choice = getInitialChoice();
    if (choice == "s") {
        getRecipeName();
    }
}

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
  • #2
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 JonnyG
  • #3
This works. Thank you.
 
  • #4
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 Vanadium 50, yungman and JonnyG
  • #5
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.
 
  • #6
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 Vanadium 50
  • #7
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) {
cout << 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).
 
  • #8
JonnyG said:
Suppose I have the code:

string in;
while (cin >> in) {
cout << 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 cout 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.
 
  • #9
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;
    cout << "Enter first line:  ";
    cin >> Cr; cout << endl;
    cout << " The first line is: " << Cr << endl;
    cout << "Enter second line:  ";
    cin >> Cr; cout << endl;
    cout << " The second line is: " << Cr << endl;

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

1. What is the difference between cin and getline?

Cin is a standard input stream that reads input from the keyboard, while getline is a function that reads input from a specified input stream, such as a text file.

2. Why do I encounter problems when using cin and getline together?

One common problem is that cin leaves a trailing newline character in the input buffer, which getline then reads as the first character in the next input. This can cause unexpected behavior and errors in your code.

3. How can I fix the problem when using cin and getline together?

You can use the ignore() function after using cin to clear the input buffer before using getline. This will discard any remaining characters in the buffer, including the newline character, allowing getline to function correctly.

4. Can I use cin and getline together in the same program?

Yes, you can use both cin and getline in the same program. However, it is important to use them correctly and handle the input buffer to avoid any unexpected behavior.

5. Are there any alternatives to using cin and getline together?

Yes, you can use the getline function with a stringstream object instead of cin. This will allow you to read from the keyboard without encountering any problems with the input buffer.

Similar threads

  • Programming and Computer Science
4
Replies
118
Views
6K
  • Programming and Computer Science
2
Replies
41
Views
3K
  • Programming and Computer Science
Replies
2
Views
876
  • Programming and Computer Science
Replies
12
Views
1K
  • Programming and Computer Science
2
Replies
65
Views
5K
  • Programming and Computer Science
Replies
4
Views
5K
  • Programming and Computer Science
Replies
5
Views
4K
  • Programming and Computer Science
Replies
4
Views
4K
  • Programming and Computer Science
Replies
3
Views
3K
Replies
10
Views
960
Back
Top