Ok, I new to this and haven't been taught exception handling yet but I would like my program to run without crashing when someone mashes the keyboard. I have declared an int x, and I don't want my program to crash when user inputs an char or more than 10 digits... what should I do?

Recommended Answers

All 10 Replies

Input the number as a string, then pop it into a stream and back out to get it back in number form.

int number;
string line;
getline(cin, line);
istringstream convert(line);
convert >> number;

Check for errors by testing the stream object after conversion.

if (convert)
    // good
else
   // bad

I'm making this calculator thing, my knowledge in c++ isn't very deep at all, I don't understand why you need to convert the int to string to test the int and see if it's a string or not? I'm confused.

>I don't understand why you need to convert the int to string to test the int and see if it's a string or not?
Because using cin to read in numbers is quite limited. If you have any doubts about it, look at the following program:

#include <iostream>
using namespace std;

int main() {
    
    int num=0;
    
    while (num != 99) {
        cout << "Please enter a number, or 99 to quit." << endl;
        cin >> num;
    }
    
    return 0;
}

Try running it and see what happens when you type in some letters instead of numbers...

Hopefully you see my point now. cin fails to read, and then everything screws up. Using strings avoids that problem, because the user can enter just about anything and they won't screw up the input buffer. Then you can manually validate the input yourself.

That's what happens with my program, when you enter a string when cin type is int, it enters some infinity loop in my while loop. I get that part now, so how do I use the if..else to test for the string and only get the numbers?

Well, if you take the examples from my first post, and implement them in the program I just showed you, you end up with something like this:

#include <iostream>
#include <sstream>
using namespace std;

int main() {
    
    int num=0;
    string line;
    
    while (num != 99) {
        cout << "Please enter a number, or 99 to quit." << endl;
        getline(cin, line);
        istringstream convert(line);
        convert >> num;
        if (!convert)
            cout << "Error, you must enter a valid number." << endl;
    }
    
    return 0;
}

It would be trivial to modify this into a loop that keeps waiting until the user enters valid input.

Thank you joeprogrammer!
Mashed my keyboard... my little calcuation program didn't crash. Perfect!

I do have a few question about istringstream since I don't know what it does:

istringstream convert(line)

Does this create a constructor class of istringstream?
What's the terminology for convert?

convert >> num;

I'm guessing 'convert' with string line parsed in it is converted to and stored in int num;

if (!convert)

not sure what convert is with the not equal syntax on it.

istringstream convert(line);
convert >> num;
if (!convert)

What would be the pseudocode for the 3 lines above, well I want to understand it as well.

After some reading I found that istringstream is used to capture stirings for using as ints and such so the above would be something like:

using the constructor from istringstream class, content of the string 'line' is copied in to its internally associated string object named 'convert'.
or something like declare string stream 'convert'
'num' reads 'convert' into memory
if not type? 'convert' do ... <- :eek: I don't understand nor have good explanation for !convert?

Another thing is do i need to include the

#include <string>

for using string in my code or does that somehow get's included when you use:

#include <sstream>

convert is the stringstream object. The convert is true or false based on the execution of the >> operator. Therefore

if (!convert)

actually says "if the previous operation was not successful..."

>I don't understand why you need to convert the int to string to test the int and see if it's a string or not?
Because using cin to read in numbers is quite limited. If you have any doubts about it, look at the following program:

#include <iostream>
using namespace std;
 
int main() {
 
    int num=0;
 
    while (num != 99) {
        cout << "Please enter a number, or 99 to quit." << endl;
        cin >> num;
    }
 
    return 0;
}

Try running it and see what happens when you type in some letters instead of numbers...

Hopefully you see my point now. cin fails to read, and then everything screws up. Using strings avoids that problem, because the user can enter just about anything and they won't screw up the input buffer. Then you can manually validate the input yourself.

I am sorry but when you say that cin has limited capability of reading the numbers what exactly do you mean. And why does it go to the infinite loop. I would be much obliged if you can reply to this as well. Thanks in advance.

>Another thing is do i need to include the #include <string> for using string in my code
It would be a good idea, yes, although I think the basic string object is included when you use iostream in your program.

>when you say that cin has limited capability of reading the numbers what exactly do you mean.
It's difficult to use it to read in numbers failproof, and plus cin has problems of its own. Using getline is a far better alternative.

>And why does it go to the infinite loop.
2 reasons:

  • Since the user has typed letters, they go into the input buffer. When you try to read them into a number, cin gets an error and "freezes up".
  • The letters keep sitting in the input buffer, so even if there weren't any errors, cin wouldn't allow the user to enter anything because there's already junk in the input buffer.

You can fix these 2 problems by using cin.clear() to get rid of the errors, and then using cin.ignore() to clear the input buffer. The order is important! If you try to clear the input buffer first, it will fail, because cin still has errors and is "frozen".

#include <iostream>
using namespace std;

int main() {
    
    int num=0;
    
    while (num != 99) {
        cout << "Please enter a number, or 99 to quit." << endl;
        cin >> num;
        
        if (!cin) {
            cout << "Error, you must enter a valid number." << endl;
            cin.clear();
        }
        // we could have put this inside the if() statement, but it's still
        // a good idea to clear the buffer, as cin leaves newlines behind
        cin.ignore(numeric_limits<streamsize>::max(), '\n');
    }
    
    return 0;
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.