Best scenario: Program loudly does the right thing.
OK scenario: Program silently does the right thing.
Bad scenario: Program loudly does the wrong thing.
Very bad scenario: Program silently does the wrong thing and you somehow discover the problem anyways.
Worst scenario: Program silently does the wrong thing and no one figures it out (until the nuclear reactor explodes).
The fourth is what you have, so it could be worse.Silent bugs are really really bad though.
If you have a big complex multi-branch conditional like yours in the Result() function, you should put a default else{} catch-all block. Your program should never reach this else{} block unless something goes wrong. So unless you have a good reason to do otherwise, in the else{} block you should make your program print a large nasty error message and die a horrible death. (Have the program exit with a return value indicating failure.) Have the error message print as much relevant information as possible. In this case I'd have it print something like this at the very least:
Putting some kind of quoting character( my [] above ) around the output variables will let you know if you're outputting a blank string or a string full of whitespace, which is a hard bug to see visually otherwise. (A good reason to use a monospace font in your console window by the way.)Code:if(strcmp(States[b].Abb, a.KeyIn) == 0) { ... } else if(strcmp(States[b].Name, a.KeyIn) == 0) { ... } else if(strcmp(States[b].Union, a.KeyIn) == 0) { ... } else { cerr << "ERROR: invalid user input: [" << a.KeyIn << "] != [" << States[b].Abb << "] [" << States[b].Name << "] [" << States[b].Union << "]" << endl; // cleanup here if necessary (close filehandles, cleanly deallocate memory, flush buffers if necceasy etc. etc.) exit(1); }
Another possibility would be to loop and re-prompt for input until you get some that's valid, rather than just having your program kill itself. Or whatever else you'd like.
If you have access to a debugger, you can use that to do the same thing in a perhaps more helpful way. Set a breakpoint somewhere in or before the Result() function, and inspect the values of all your data structures as of that moment.
In general you should put those kind of error checks in every program you write, to cover every possible thing you can imagine that could be broken, and then some. Imagine the file doesn't exist. Imagine the file exists but is full of gibberish. Imagine a directory exists with the same name as the file you want. Imagine the file exists but you have no permissions to read it. Imagine the user enters a single space as his input. Imagine the user somehow manages to enter nothing as the input. Imagine the user enters 1000 characters of gibberish. Imagine the user enters numbers if you're expecting text, or text if you're expecting numbers.
A good program will gracefully handle all of those things. At the very least, complain loudly. At most, die a horrible death. If you build this kind of checking into your program as you write it, you will find that it's very easy to debug, and very easy for users to use (or at least easy for you to fix once the user starts complaining to you that it's broken).



Silent bugs are really really bad though.
Reply With Quote