If a user wa开发者_StackOverflow社区s to enter a letter instead of an integer, the loop goes wild. I know how to get rid of that error
cin.clear() and cin.ignore()
But I haven't been able to understand why it happens. A character is represented by an integer from 0 to 255. And each number is 32 bit enough for the integer variable to handle..so why does the stream fail then?
Is it possible to use exception to test for this errors, I am trying to understand exceptions, and I wasn't able to write code for that.
Why do they work like this:
Well the stream operators >> and << are designed to read text (or human readable streams (or files)). Thus when used you are expecting a certain type of input that has a particular form:
int a;
stream >> a; // I expect the stream to contain an integer in human readable form.
MyClass x;
stream >> x; // I expect the class to contain a serialize version of x;
If a char was auto converted into an integer the stream would not work the way most people expect the stream operators to work (ie read human readable forms). i.e. do you know what the ASCII value of 'z' is supposed to be? Do you even know if your platform represents characters as ASCII? etc there are a lot of questions that are only half know if we took this route.
Now if you want to treat your file as a binary value. You could read the a single byte out and treat it as an integer.
char y;
stream.read(&y, 1); // Read a single byte into y
int x = y; // now convert the byte to an integer.
Moving to Exceptions:
Exceptions are good when you handle errors separately from the processing. This is fine when you have huge files and an error in the file input usually means corruption and you should stop processing. Then exceptions are the perfect solution.
But simple examples though you are usually processing user input. Detecting and fixing user input is usually done at the site of the processing and thus exceptions are not the best solution for the problem.
std::cout << "Enter a number\n";
int number;
while(!(std::cin >> number))
{
std::cout << "That was not a number\n";
std::cin.clear();
std::cin.ignore();
}
// With exceptions:
// That's too much work.
But if I am processing a google index:
// If the read fails get out of here with an exception.
while(data >> x >> y >> z >> j >> q >> p >> src >> dst)
{
doWork();
}
ExapndAndGrok();
// Handling the errors:
while(data >> x >> y >> z >> j >> q >> p >> src >> dst)
{
doWork();
}
if (testDataStreamForSomeError(data)) // EOF is not an error.
{
throw someException("The input failed");
}
ExapndAndGrok();
Yes, you can tell any stream to throw an exception (instead of just setting fail bits) using ios::exception.
cin.exceptions(istream::failbit | istream::badbit);
try
{
int a;
cin >> a;
}
catch(istream::failure& e)
{
cerr << "Error : " << e.what() << endl;
}
You can write the loop as:
int var;
while ( std::cin >> var )
{
//do whatever you want to do with var
}
If you enter anything other than integers, the loop will break. That means, if you enter letters, punctuations, floating-point numbers, whatever, the loop will exit, and that would imply that something gone wrong in the input stream.
But I haven't been able to understand why it happens. A character is represented by an integer from 0 to 255. And each number is 32 bit enough for the integer variable to handle..so why does the stream fail then?
Well the spec says when you use operator >> to an int, it needs to parse the input as a text representation of an integer (according to the currently imbued locale, though in the case of int, that probably doesn't matter much). This means that, unless you also use an io manipulator to accept non-default radix (like ios::hex
for example) alphanumerics are off-limits by definition.
If you want to accept any char and treat it as a binary representation of a 'short short integer', you can
unsigned char uch;
signed char sch;
std::cin >> uch;
std::cin >> sch;
As you'd correctly expect, this would never fail for parsing reasons (only eof(), permission denied, out of memory, or some other technical failure...).
Hope that explains
精彩评论