我想知道在编程中处理错误的最佳方法是什么(我用C编码)。我是程序员的新手,这就是我正在做的事情:
if( action1 was successfull )
{
[some code]
if (action 2 was successfull)
{
[some more code ..]
if (action 3 was successfull)
{
ETC ...
}
else
{
[Handle error3]
}
}
else
{
[handle error2]
}
}
else
{
[Handle error1]
}
但我认为这是一个糟糕的习惯......有人可以向我解释一下,最优雅的方式是什么? 感谢
答案 0 :(得分:4)
我这样做:
// more code
if (!action_1_succeeded())
{
handle_error();
return;
}
// more code
if (!action_2_succeeded())
{
handle_error();
return;
}
// more code
if (!action_3_succeeded())
{
handle_error();
return;
}
通常,我会将handle_error
和return
打包成一个宏,所以我只做check_error(some_statement());
答案 1 :(得分:4)
有时候你展示的代码确实是最好的选择,但这里有一些选择。
通常你可以这样构建你的代码:
if (action_1() failed) {
report error;
return -1;
}
if (action_2() failed) {
report error;
return -1;
}
/* etc */
这个结构就是为什么在成功时返回0或在失败时返回-1的常见C语言:它允许你将if (action_1() failed)
写为if (action_1())
。
如果你需要在返回之前进行一些清理,并且清理行动整齐地嵌套,这是另一种可能性:
if (action_1()) {
report error;
goto fail_a1;
}
if (action_2()) {
report error;
goto fail_a2;
}
if (action_3()) {
report error;
goto fail_a3;
}
/* etc */
return 0;
/* errors */
/* etc */
fail_a3:
clean up from a2;
fail_a2:
clean up from a1;
fail_a1:
return -1;
特此授权您使用goto
来执行此操作。
答案 2 :(得分:1)
您可以创建错误ID并将错误处理程序与特定类型的错误相关联。
typedef struct _error {
void (*handler)(struct _error *);
int i_params;
char *c_params;
} error;
void nope(error * e) {}
void file_err(error * e) { exit(1); }
error handlers[200];
void check_error(int id) {
handlers[id].handler(&handlers[id]);
}
enum error { ER_SUCCESS, ER_FILE};
int main() {
handlers[ER_SUCCESS].handler = nope;
handlers[ER_FILE].handler = file_err;
check_error(action1());
return 0;
}