2013-03-14 53 views
5

我的程序等待用戶輸入,並在適當時處理它。我需要檢查用戶輸入以確保它符合某些標準,如果它不符合所有這些標準,它將被拒絕。優雅地檢查用戶輸入錯誤

僞代碼是一樣的東西:

if (fulfills_condition_1) 
{ 
    if (fulfills_condition_2) 
    { 
     if (fulfills_condition_3) 
     { 
      /*process message*/ 
     } 
     else 
      cout << error_message_3; //where error_message_1 is a string detailing error 
    } 
    else 
     cout << error_message_2; //where error_message_2 is a string detailing error 
} 
else 
    cout << error_message_1; //where error_message_3 is a string detailing error 

有這種可能性,即這些條件的數量可能會增加,我想知道是否有一個更合適的方法來表示這個使用交換機或類似的東西而不是大量的級聯if陳述。

我知道有使用

if (fulfills_condition_1 && fulfills_condition_2 && fulfills_condition_3) 
    /*process message*/ 
else 
    error_message; //"this message is not formatted properly" 

的可能性,但是這是比第一用處不大,並沒有說哪裏的問題。

的條件大致可安排在日益增加的重要性,即檢查condition_1比檢查condition_3更重要,所以if報表做的工作 - 但有一般這樣做的更好的辦法?

+1

例外..... – 2013-03-14 08:55:29

+0

您是否考慮過使用try-catch和異常類進行負面條件檢查,該類能準確反映首先觸發問題的條件? – WhozCraig 2013-03-14 08:55:51

+0

這取決於你的輸入有多複雜。我將創建一個DSL來聲明輸入是如何有效的,並創建表示該DSL的對象,然後說驗證該輸入。 – 2013-03-14 09:02:08

回答

2

如何

if (!fulfills_condition_1) throw BadInput(error_message_1); 
if (!fulfills_condition_2) throw BadInput(error_message_2); 
if (!fulfills_condition_3) throw BadInput(error_message_3); 

/* process message */ 

然後你的異常處理程序會報告錯誤消息,並且重試或酌情中止。

1

我建議你可以使用「早日重返」技術:

if (!fulfills_condition_1) 
    // error msg here. 
    return; 

    // fulfills_condition1 holds here. 

    if (!fulfills_condition_2) 
    // error msg here. 
    return; 

    // Both conditon1 and condition2 hold here. 

    if (!fulfills_condition_3) 
    // error msg here. 
    return. 
2

如果有什麼困擾你的級聯if S,你可以去以下之一:

使用布爾:

bool is_valid = true; 
string error = ""; 
if (!condition_one) { 
    error = "my error"; 
    is_valid = false; 
} 

if (is_valid && !condition_two) { 
    ... 
} 

... 

if (!is_valid) { 
    cout << error; 
} else { 
    // Do something with valid input 
} 

使用異常:

try { 
    if (!condition_one) { 
    throw runtime_error("my error"); 
    } 

    if (!condition_two) { 
    ... 
    } 

    ... 

} catch (...) { 
    // Handle your exception here 
} 
1

如果這將在幾個地方被重用,我會做一個DSL:

Validator inputType1Validator = 
    Validator.should(fulfill_condition_1, error_message_1) 
      .and(fulfill_condition_2, error_message_2) 
      .and(fulfill_condition_3, error_message_3) 

inputType1Validator.check(input);