2012-02-06 168 views
0

我想知道什麼是最好的方式來處理程序錯誤(我在C編碼)。我在programmation一個新手,這是我在做什麼:如何處理錯誤

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] 
} 

但我認爲這是一個不好的習慣中......有人能向我解釋什麼是最優雅的方式來做到這一點? 感謝

回答

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_errorreturn成宏,所以我只是做check_error(some_statement());

+0

這絕對是代替例外的最好方法。總是首選* flat *到*嵌套* – 2012-02-06 17:58:21

+0

您的action_x_succeeded()是否在某處設置了一個變量來知道處理了哪個錯誤? – Eregrith 2012-02-06 18:02:35

4

有時候你展示真正的代碼是最好的可用的選項,但這裏有一些選擇。

通常你可以構建你這樣的代碼來代替:

if (action_1() failed) { 
    report error; 
    return -1; 
} 
if (action_2() failed) { 
    report error; 
    return -1; 
} 
/* etc */ 

此結構是爲什麼它是一個通用的C成語或-1失敗成功返回0:它可以讓你寫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

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; 
}