Reputation: 674
I'm trying to read multiple Strings
and ints
from the user. I want to take pairs of Name and Age and keep doing it until the user types in "done". But my do-while
crashes early on, and i can't figure out why?
int number;
string name;
do
{
cout << "Your name: " ;
getline(cin, name);
cout <<name<< " age: " ;
cin >> number;
}
while (name!="done");
Edit: Also after entering "done", i have to enter "done" also on age, why is that?
Upvotes: 1
Views: 3019
Reputation: 19767
#include <iostream>
#include <string>
int main ()
{
std::string name;
int age;
while (true)
{
std::cout << "Please enter your name: ";
std::cin >> name;
if ( "done" == name )
break;
std::cout << name << ", please enter your age: ";
std::cin >> age;
std::cout << name << ", you are " << age << " years old\n";
}
std::cout << "Bye.\n";
return 0;
}
Mixing use of getline()
and >>
can be problematic. Best to just avoid it if you can. You could also use getline()
for both, and convert the int
using a stringstream
, or possibly atoi()
, but I don't like that much.
Upvotes: 1
Reputation: 9403
Use the std namespace
This way
int number;
string name;
do
{
std::cout<<"Your name: " ;
std::cin>>name;
std::cout<<name<<" age: " ;
std::cin>>number;
}
while (name!="done");
Or this
using namspace std;
int number;
string name;
do
{
std::cout<<"Your name: " ;
std::cin>>name;
std::cout<<name<<" age: " ;
std::cin>>number;
}
while (name!="done");
Upvotes: 1
Reputation: 390
I tried to run your program in VS 2010, and even when I entered a valid number, the program would, to my surprise skip reading the next name.
It seems to me that cin >> number
doesn't swallow the '\n' I naturally entered after the number.
I attempted adding a call to getchar() after each cin >> number
and the program suprisingly started working as expected.
So the conclusion is, that you should clean()/ignore() after cin >> number
even after the number entered was OK, or resort to using getline() (and then parsing) for reading numbers.
If you want not to input "done"'s age then you have to break out of the loop immediately after it's entered. My final code:
#include <iostream>
#include <string>
using namespace std;
int main()
{
int number;
string name;
while(true)
{
cout << "Your name: " ;
getline(cin, name);
if(name == "done")
break;
cout <<name<< " age: " ;
cin >> number;
cin.clear();
cin.ignore(std::numeric_limits<streamsize>::max(),'\n');
}
}
Upvotes: 2
Reputation: 2362
Because you give it a string while it expect an int as age
.
At the end of the first iterate, as you typed the Enter key to input the age
, an extra newline was taken into the cin
. So in the second iterate, the newline showed up as an empty line, causing the name
to be set as an empty string. Then the program wanted an int as age
. If you are not careful enough, you would input a string and cause the program crash.
One suggestion: To replace:
getline(cin, name);
with:
do {
getline(cin, name);
} while (name.empty());
Upvotes: 0
Reputation: 31435
If someone enters an invalid age, i.e. something that isn't a number, you need to clear the flags of your cin, and also flush any remaining characters.
if( !(cin >> number )
{
cin.clear();
}
cin.ignore( std::numeric_limits<streamsize>::max() );
If it does read a number then you also need to ignore the newline after it.
Upvotes: 2