Why does this code not work?

Hello everyone,

I am an absolute noob in C++ and just started learning it a few hours ago.
I am just wondering, why it won't let me enter the favorite color when I write it like this.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
  #include <iostream>

using namespace std;

int main()
{
   string favcolor;
   string name;
   int age;

   cout << "Hello" << endl;
   cout << "Enter your Name: ";
   getline(cin, name);
   cout << "Enter your Age: ";
   cin >> age;
   cout << "Enter your favorite color: ";
   getline(cin, favcolor);
   cout << " " << endl;

   cout << "Good Morning " << name << endl;
   cout << "You are " << age << " years old" << endl;
   cout << "And your favorite color is " << favcolor << endl;
   cout << " " << endl;
   cout << "The data you provided is now stored in our system" << endl;
   cout << "Thanks :)";
   cout << " " << endl;

    return 0;
}


If I switch the order to first "Enter your favorite color" and then "Enter your Age" like this, it works. But I dont understand why.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>

using namespace std;

int main()
{
   string favcolor;
   string name;
   int age;

   cout << "Hello" << endl;
   cout << "Enter your Name: ";
   getline(cin, name);
   cout << "Enter your favorite color: ";
   getline(cin, favcolor);
   cout << "Enter your Age: ";
   cin >> age;
   cout << " " << endl;

   cout << "Good Morning " << name << endl;
   cout << "You are " << age << " years old" << endl;
   cout << "And your favorite color is " << favcolor << endl;
   cout << " " << endl;
   cout << "The data you provided is now stored in our system" << endl;
   cout << "Thanks :)";
   cout << " " << endl;

    return 0;
}


Thanks for your help.
Last edited on
cin >> age; cin.ignore( 1000, '\n' );

Your stream extractor >> leaves the newline character in the stream, confusing any subsequent call to getline.
Last edited on
Thanks a lot for your fast reply!

I am not gonna lie, it took me a few minutes and some google searches to understand what you are saying but I think I understand it now (or at least most of it).

If anyone is just as new as I am to C++ and encountered a similar problem, I encourage you to read through this thread.

https://stackoverflow.com/questions/5131647/why-would-we-call-cin-clear-and-cin-ignore-after-reading-input



Here is the explanation for this exact problem from the thread mentioned above:

Every time you put something on input (stream) you leave at the end white character which is ENTER ('\n') You have to somehow enter values to console. So it must happen if the data comes from user.

b) cin characteristics is that it ignores whitespace, so when you are reading in information from cin, the newline character '\n' doesn't matter. It gets ignored.

a) getline function gets the entire line up to the newline character ('\n'), and when the newline char is the first thing the getline function gets '\n', and that's all to get. You extract newline character that was left on stream by user who put "20" on stream in line 3.

So in order to fix it is to always invoke cin.ignore(); each time you use cin to get any value if you are ever going to use getline() inside your program.
b) >> ignores initial whitespace. It's not specific to cin. This is for any file stream - of which cin refers to the keyboard.

a) getline () gets all chars from the current file stream position up t and including the specified terminating char. if a terminating char is not specified, then the default '\n' is used.

As an alternative to using .ignore() on the file stream either after a >> or before a getline(), you can do this (needs #include <iomanip> ):

 
std::getline(std::cin >> std::ws, line);


This first ignores any/all white space chars (space, tab, \n) from the specified stream before the data extraction.

The issue with using .ignore() is that it only ignores 1 char. what if the input is say '123 \n' first and then 'green'. The ignore will only ignore one trailing space after 3 and then the getline() will get ' \n' !

If you want to use ignore, then:

 
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');


which will ignore all chars upto and including the '\n'. Note that this needs #include <limits>
As an alternative to using .ignore() on the file stream either after a >> or before a getline(), you can do this (needs #include <iomanip> ):
std::getline(std::cin >> std::ws, line);


Actually, I would have said that too.

However, it "failed" (well, sort of) on both my PC and in cpp.sh because of buffered output. I ended up having to add a " << flush" to the following line.

If you can enter your favourite colour without prompting first then it sort of works.


Another method is simply to use a getline() call with a dummy string variable. Most of the time it fills it with an empty string, but at least it clears the newline and you don't have to worry about unwanted output buffering.
1
2
   string dummy;
   cin >> age;   getline( cin, dummy );   // This getline purely clears the end of line 
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
#include <iomanip>

using namespace std;

int main()
{
	string favcolor;
	string name;
	int age {};

	cout << "Hello\n";

	cout << "Enter your Name: ";
	getline(cin, name);

	cout << "Enter your Age: ";
	cin >> age;

	cout << "Enter your favourite colour: ";
	getline(cin >> ws, favcolor);
	cout << '\n';

	cout << "Good Morning " << name << '\n';
	cout << "You are " << age << " years old\n";
	cout << "And your favourite colour is " << favcolor << '\n';
	cout << '\n';
	cout << "The data you provided is now stored in our system\n";
	cout << "Thanks :)\n";
}



Hello
Enter your Name: seeplus
Enter your Age: 123
Enter your favourite colour: coffee

Good Morning seeplus
You are 123 years old
And your favourite colour is coffee

The data you provided is now stored in our system
Thanks :)


cin is tied to cout and cout should be flushed before input is obtained. It works as expected using MS VS2019 on my Windows 7 computer.
Last edited on
cin is tied to cout and cout should be flushed before input is obtained

Well, you can try it on cpp.sh ...
All bets are off with on-line compilers - especially one that hasn't been updated since C++14......
Topic archived. No new replies allowed.