My little brother, to whom I show my little programs regularly, always laughs at the fact that all he needs to do to crash them is type letters into the variable inputs. Can I stop him doing this with an error message?
(At the moment, I'm not concerned with how to reset the program or anything. All I want is an error message.)
My current code is this:
1 2 3 4 5
cout << "Input a variable."; double x_h; cin >> x_h;
if (!(x_h<1e100 && x_h>-1e100))
{cout << "Error: your number is too big or small. Try again next time.";
exit(1);}
This works if the number is obscenely big or small. Is there any way to modify this so I can test to see if the variable a letter?
When I need to idiot-proof my inputs in C++, I usually have the data read into a stringstream, check the string for anything that isn't allowed to be there (stray characters, invalid syntaxes), and then output it into the variable(s) of choice from the stringstream.
The same can be done with cin, for that matter, avoiding the getline/stringstream altogether.
(Albeit slightly differently... you won't check for eof, and you will need to reset the stream state and clear the input stream on error (2 lines of code).
If you're only dealing with numbers, I agree. However, if you're dealing with strings too, you'll
probably want to use getline. And if you're going to use getline, it's better to use it for numbers too.
Thanks everyone, but I'm very new to programming in general. As a result, m4aster r0shi's links kind of went over my head a bit. Is there a simple way to explain what a stringstream (or a string, for that matter) is?
Does "break" mean just come out of the endless "while" loop?
Is <sstream> only used to include the stringstream function?
And what is the purpose of the <string> header?
What does the getline function do?
And what does .eof mean, and why does it relate to what's trying to be done?
stringstream provides an interface to manipulate strings as if they were input/output streams
You can think of stringstreams as cin/cout objects, except the
data got/put from/to keyboard/screen is got/put from/to strings.
TentPegSlayer wrote:
And what does .eof mean, and why does it relate to what's trying to be done?
Treating buffer as a bool is a shortcut to writing buffer.good(). If an input operation fails for any reason, buffer.good() returns false.
EOF stands for End Of File. If buffer's internal string is consumed, buffer.eof() returns true. I'll try to answer this using examples.
enter a number: abc123
dude... wtf? -.- // number is untouched, bool(buffer) is false, buffer internal string is "abc123", buffer.eof() is false
enter a number: 123abc
dude... wtf? -.- // number is set to 123, bool(buffer) is true, buffer internal string is "abc", buffer.eof() is false
enter a number: 123
you entered: 123 // number is set to 123, bool(buffer) is true, buffer internal string is "", buffer.eof() is true
Using stringstreams is the preferred method (and is easier then the one below, once you fully understand them.) However, here is an example using just strings to help you understand why reading input from cin into a string will allow you to validate your data.
#include <iostream>
#include <string>
usingnamespace std;
int main() {
string str; //create a string (the C++ version of char[])
getline(cin, str); //read a line of text from cin, unlike "cin >> str" which only reads to the first whitespace character
//WARNING: Using "getline(cin, __)" and "cin >> __" in the same program will cause unintuitive behavior
for( int i = 0; i < str.length(); i++ ) //loop through each charecter of str
if( str[i] < '0' || str[i] > '9' ) { //if str[i] is not one of the characters between '0' and '9', i.e. str[i] is not a digit
cerr << "ERROR: Why do you do this?" << endl; //print an error message to cerr (the standard error stream)
return 1; //finish (quit/exit) our program, and return an error code to the environment signifying that the program did not run correctly
}
//if we make it here then all the characters in str must be digits
double num = aotf( str.c_str() ); //one way to parse (convert, interpret) the string str as a double
//NOTE: str.c_str() will return the equivalent char[] (char*, null-terminated, C string)
... //do stuff with num
return 0;
}