Jump to content
  • Advertisement
Sign in to follow this  
gah_ribaldi

Surely there's a way to... - c++

This topic is 3971 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

int price;
cout << "Enter amount of gold to send to Fred: "
cin >> price;

it looks so simple. But then the user enters 27u or something else which doesn't match the expected type, and before you know it the program falls over and starts stabbing itself in the eye. Is there a nice neat way to just reprompt?

Share this post


Link to post
Share on other sites
Advertisement
One way would be:

int price;
do {
std::cout << "Enter amount of gold to send to Fred: ";
if (!std::cin) {
std::cin.clear();
std::cin.ignore(std::cin.rdbuf()->in_avail());
}
std::cin >> price;
} while (!std::cin);

Though your code would accept "27u" as an input. It would parse it as 27 and leave the "u" in the input stream. To take that into account you can read by line and parse out via a stringstream. Ex:

int price;
for (;;) {
std::cout << "Enter amount of gold to send to Fred: ";
std::string text;
std::getline(std::cin, text);
std::istringstream sstr(text);
sstr >> price;
if (!sstr.fail() && !sstr.rdbuf()->in_avail()) break;
}

Share this post


Link to post
Share on other sites
Quote:
Original post by SiCrane
One way would be:

int price;
do {
std::cout << "Enter amount of gold to send to Fred: ";
if (!std::cin) {
std::cin.clear();
std::cin.ignore(std::cin.rdbuf()->in_avail());
}
std::cin >> price;
} while (!std::cin);

Though your code would accept "27u" as an input. It would parse it as 27 and leave the "u" in the input stream. To take that into account you can read by line and parse out via a stringstream. Ex:

int price;
for (;;) {
std::cout << "Enter amount of gold to send to Fred: ";
std::string text;
std::getline(std::cin, text);
std::istringstream sstr(text);
sstr >> price;
if (!sstr.fail() && !sstr.rdbuf()->in_avail()) break;
}


Nice. Would that code cope with 2u7 though?

Share this post


Link to post
Share on other sites
What do you think? In particular, what do you think this line does?

if (!sstr.fail() && !sstr.rdbuf()->in_avail()) break;

Share this post


Link to post
Share on other sites
Quote:
Original post by SiCrane
What do you think? In particular, what do you think this line does?

if (!sstr.fail() && !sstr.rdbuf()->in_avail()) break;


Well, I'm not familiar with stringstreams and would have to do a bit of digging to fully understand the command but that looks like it'll only break out of the infinite loop you made if the stringstream didn't fail (not sure what activates fail since I'm unfamiliar with it) AND there's nothing left for it to run through.

So... the code runs through the string throwing away any unwanted characters and when it gets to the end exits gracefully leaving me with what I want.

Yes? Hmm. Maybe "not quite". I'm not sure what would happen if the user typed in "abc"

Share this post


Link to post
Share on other sites
fail() will return true if any formatted extraction operations didn't succeed. So putting in "abc" will cause fail() to return true, so the loop would repeat from the top. The in_avail() would check to see if there are any characters unused when reading the integer. So when reading "2u7" it would stuff the 2 into price, but fail() wouldn't return true since it managed to read some integer, but "u7" would be left in the buffer, so in_avail() would return 2, and the loop would repeat from the top.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!