I'm trying to get a grip on exception handling and am going nowhere.
I picked a simple beginning error that I've had when coding:
Getting an integer input from user. The error would be a non-integer (float/character). I tried my own code (try, throw, catch) and couldn't stop getting some weird behaviour.
Could anyone help me get a real feel for this?
I have a list of error codes but no idea what the meanings mean.
I'd like not just one way of doing it but a few for an idea of some language complexities. Maybe some basic and a bit advanced.. not too advanced, I'll be back for those in awhile ;)
#include <iostream>
#include <stdexcept>
usingnamespace std;
int main()
{
int a;
while (cout << "Enter an integer: ") {
try {
if (cin >> a)
cout << a << '\n';
elsethrow runtime_error("Error!");
} catch (runtime_error err) {
std::cout << err.what()
<< "\nTry Again? Enter y or n\n";
char c;
cin >> c;
if (!std::cin || c == 'n')
break;
}
}
return 0;
}
The problem here (I think) is that (when I enter a float e.g. 1.5) cin >> c doesn't wait for input, execution carries on to the next line. Possibly cin needs to be flushed first because of the incorrect data type? How would this be done?
It is incorrect usage of exceptions: if you know how to handle problem locally, you should do so. Exceptions are needed to notify parent code about problem and to let it handle the problem themselves.
Here read_from_file does not know what to do in case of problem. Should it return some default object? Should it fail? Should it create new file? Should it do that everytime?
That function can be used in many places, each of which migh require own problem handling. So best way for read_from_file to handle problem is to delegate it to the calling function.
In my example, it will create a new default file if file does not exist, but will do nothing if file is corrupt.
In your case you should just use condition statements to handle incorrect input.
Okay. Condition statements. How?
Anything trying to input a non-int into an int causes weird issues. Generally what I get is the cin failing every time after this (i.e. cin doesn't stop program flow to receive input but keeps passing the same non-int (when in a loop as above).
In case you don't know what I mean, this code causes the same problem
1 2 3 4 5 6 7 8 9 10 11 12 13
#include <iostream>
usingnamespace std;
int main()
{
int a;
while (cout << "Enter an integer: ") {
if (cin >> a, cout << a << endl);
else (cout << "Error: not an integer");
}
return 0;
}
(when I enter a float e.g. 1.5) cin >> c doesn't wait for input
When you read an int, extraction operator reads stuff up until first non-digit, and leaves rest for further input operations.
In your case it reads 1 and leaves .5 for further reads. Next read tries to read . as int and fails, setting stream in failed state and leaves offending input in stream.
You need to handle that incorrect input and reset stream state afterwards:
Because you want to catch stuff like 1.5 and 44asd and threat them as invalid input. In correctly entered data there is always a whitespace character (a space, tab or newline) after input (POSIX says that files should be terminated with a newline, so it holds true for last input as well).
This is two inputs entered as one line (whitespace delimited input is native for C++). If you want that everything on line to be threated as single input you need different algorithm — different requirements = different code.