Handsken
Handsken

Reputation: 674

While loop fail, when reading int and string C++

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

Answers (5)

BoBTFish
BoBTFish

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

Akhil Thayyil
Akhil Thayyil

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

user1227804
user1227804

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

Ade YU
Ade YU

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

CashCow
CashCow

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

Related Questions