Reputation: 183
what happens when you cin>> letter to int variable? I tried simple code to add 2 int numbers, first read them, than add them. But when I enter letter, it just fails and prints tons of numbers to screen. But what causes this error? I mean, I expected it to load and use ASCII code of that letter.
Upvotes: 10
Views: 11102
Reputation: 12202
When you are doing something like:
int x;
cin >> x;
You are instructing C++ to expect to read an int
from keyboard. Actually, when you enter something not an int
, the input stream (standard input, in this case) renders unusable due to its error state.
That's why I personally prefer to always read strings, and convert them to numbers if needed. There are conversion functions in the C part of the C++ standard library that can help with this.
double cnvtToNumber(const std::string &num)
{
char * ptr;
double toret = strtod( num.c_str(), &ptr );
if ( *ptr != 0 ) { // If it got to the end of the string, then it is correct.
throw std::runtime_error( "input was not a number" );
}
return toret;
}
Here you are converting a number, and detecting if the conversion was right. strtod(s)
will only stop when finding the end of the string, or a space. In order to avoid trailing spaces fooling the function, you could need a trim function:
std::string &trim(std::string &str)
{
// Remove trailing spaces
unsigned int pos = str.length() -1;
while( str[ pos ] == ' ' ) {
--pos;
}
if ( pos < ( str.length() -1 ) ) {
str.erase( pos + 1 );
}
// Remove spaces at the beginning
pos = 0;
while( str[ pos ] == ' ' ) {
++pos;
}
if ( pos < 1 ) {
str.erase( 0, pos );
}
return str;
}
Now you can safely read from console (or whatever other input stream):
int main()
{
std::string entry;
try {
std::getline( std::cin, entry );
int age = cnvtToNumber( trim( entry ) );
std::cout << age << std::endl;
} catch(const std::exception &e) {
std::cerr << e.what() << std::endl;
}
}
Of course you can lose precision if you always read double
's and then convert them. There are specific functions for integers (strtol(s)
), in case you want to investigate further.
Upvotes: 1
Reputation: 57678
The issue is that when you read into an integer variable, using C++ streams, the input method expects characters that can make up a number, such as '+', '-', '0' ... '9'. Any character that is not in this set terminates the input and a number is created from these characters.
To get the ASCII value of a character, you need to input the data into a char
variable. Internally, it has the ASCII value (provided the program in not reading 16-bit chars or EBCDIC). If you want to see the ASCII value, you will need to output the char
variable as an integer (generally requiring a cast before output).
If reading an integer fails, your program needs to inform the User that the input was incorrect. The program may require the User to input the number again before the program can process the input data.
Upvotes: 1
Reputation: 8834
I assume you have code like this:
int n;
while (someCondition) {
std::cin >> n;
.....
std::cout << someOutput;
}
When you enter something that cannot be read as an integer, the stream (std::cin) enters a failed state and all following attempts at input fail as long as you don't deal with the input error.
You can test the success of an input operation:
if (!(std::cin >> n)) //failed to read int
and you can restore the stream to a good state and discard unprocessed characters (the input that caused the input failure):
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
Another possibility is to accept input into a string variable (which rarely fails) and try to convert the string to int.
This is a very common problem with input and there should be tons of threads about it here and elsewhere.
Upvotes: 10
Reputation: 63190
if you explicitly cast your char to an int, it'll use the ASCII code, else it's not doing the cast by itself to int, so you get the strange results you are getting.
Upvotes: 3