tags:

views:

72

answers:

3

Consider a scenario where a console application asks for a series of inputs, one after the other. Each input is validated before proceeding to the next. Now if an input made by the user is invalid, an error message is shown and the user is asked if he/she wants to continue. If the user chooses no, the input process is aborted. If the user chooses yes, the user is allowed to retype the input again, and the process continues by asking for the remainder of the inputs.

If I used a read() method to handle the user inputs (which also validates the input and asks if the user wishes to continue [y/n]) that returns false if the user chooses not to continue, then I would have to check for the result of every read() call before proceeding to the next

For example:

 bool valid = read("Name");
 if (valid) valid = read("Age");
 if (valid) valid = read("Sex");
 if (valid) valid = read("DoB");

 if(valid)
 {
    // do stuff
 }

Alternatively, I can have the read() method throw an exception if the user chooses to discontinue, in which case my code would become:

 try {
    read("Name");
    read("Age");
    read("Sex");
    read("DoB");

    // do stuff
 }catch(input_exception& e)
 {}

Which of these approaches would you choose and why? (Assume that the read() method throws the exception properly after cleaning up)

NOTE: I'm not looking for arguments for and against exceptions, which is abundantly available on SO. I'm only looking for an answer to the specific question.

+4  A: 

I would not use exceptions in this way, as exceptions are not meant for use as a mechanism of control flow. They exist to catch, literally, exceptional circumstances, not reasonably-expected input as in the case you describe.

There are several options for coding this using a different pattern, whether using a flag, or an if-chain, or even chaining the statements together with a boolean expression as suggested in another answer (that would be my preferred method as well). All have their pros and cons, but exceptions, IMO, are definitely not the way to do this.

phoebus
I wish more people understood this.
vanja.
+1 for *exceptions for exceptional circumstances*
Georg Fritzsche
-1 for _exceptions for exceptional circumstances_ (it is self-referential and thus not useful, even if it sounds catchy)... but +1 for recommending against exceptions in general... so I guess I'll abstain from voting (^:
Tom
It's not self referential, as the term "exception" or "exceptional", as a non-computer term, is the source for the programming construct that shares its name.
phoebus
The fact that you don't understand that is just another reason people do things like use exceptions for flow control, or expected input.
phoebus
+10  A: 

I, personally, would do it something like this:

bool valid = read("Name")
          && read("Age")
          && read("Sex")
          && read("DoB");

It's equivalent to the first code you posted. The && operator in C++ evaluates terms left-to-right and stops when a false outcome is encountered. This is not a compiler-specific hack, but well-defined behavior in C, C++, and many many other programming languages based on or inspired by C.

This also works for ||, but it stops when a true value is encountered rather than a false one.

Joey Adams
You seem to have beaten me to it by about a minute. +1 for faster typing! :-)
Jerry Coffin
+1ed both answers :)
Mystic
+5  A: 

I think I'd use the first approach, but structure it a bit differently:

bool valid = read("Name") && read("Age") && read("Sex") && read("DoB");

At least if I understand your requirements correctly, this seems to be a simpler way to meet them than either of the above.

Jerry Coffin