2017-03-29 65 views
0

我有這個函數需要從main獲得一個字符串。該字符串包含用戶可以從某些菜單選項輸入的所有有效字符。函數會將字符輸入放入一個變量中,並與字符串的每個字符進行比較。將輸入變量與字符串字符進行比較,直到輸入有效輸入。一些編碼慣例/標準練習題

我的問題是,什麼是實現這個循環的最佳方式?我不喜歡在中間使用while (true)return,因爲它看起來像一個無限循環,中間有一個例外,這使得它稍微難以閱讀,但我不知道我該怎麼做我想做的事情去做。實現我的目標的最佳做法是什麼?謝謝。

char getValidKey(string validKeys) 
{ 
    char letter; 

    while (true) { 
     cout << "Operation ? "; 
     cin >> letter; 
     cin.ignore(numeric_limits<streamsize>::max(), '\n'); 

     for (int i = 0; i < validKeys.length(); i++) { 

      if (letter == validKeys[i]) 
       return letter; 
     } 

     cout << "Error. Invalid input.\n"; 
    } 
} 

此外,我有一個switch語句具有多個返回。將計算分配給變量並在最後有一個返回或者這種方式通常可以嗎?

string opStr; 

switch (myOperation) { 
    case 1: 
     opStr = "RIGHT"; 
     break; 
    case 2: 
     opStr = "LEFT"; 
     break; 
    case 3: 
     opStr = "CENTER_ONLY"; 
     break; 
    case 4: 
     opStr = "CENTER_MISSING"; 
     break; 
    default: 
     opStr = "Error. Invalid input."; 
     break; 
} 

return opStr; 

OR

switch (myOperation) { 
    case 1: 
     return "RIGHT"; 
     break; 
    case 2: 
     return "LEFT"; 
     break; 
    case 3: 
     return "CENTER_ONLY"; 
     break; 
    case 4: 
     return "CENTER_MISSING"; 
     break; 
    default: 
     return "Error. Invalid input."; 
     break; 
} 
+2

在第二個例子中'之開關,你並不需要甚至不需要'break',因爲它不會,永遠,達到 - 使得它比第一個例子短。 –

+0

'std :: find'可以代替你的'for'循環。它只是第一次看起來更復雜,最終你會感激給你的循環有意義的名字。 – nwp

+0

1.你可以這樣做,但我更喜歡'bool running = true; while(running){... if(some_condition){running = false;}}',但這是個人的品味。 2.這兩個開關分配看起來都很好。做你喜歡的。在第二種情況下,你甚至可能想要刪除這些休息時間。在大多數情況下,您可能會使默認情況下中斷,然後在切換後返回錯誤。總之:在這些情況下,你所有的選擇都很好,只需要決定一種風格並保持它。 – Aziuth

回答

4

對於第一種情況,重構你的代碼在較小的自包含的功能,它變得清楚,甚至從while(true)瞭解getValidKey邏輯:

char isKeyValid(char x, const string& validKeys) 
{ 
    return validKeys.find(x) != string::npos; 
} 

char readCharFromCin() 
{ 
    char letter; 

    cout << "Operation ? "; 
    cin >> letter; 
    cin.ignore(numeric_limits<streamsize>::max(), '\n'); 

    return letter; 
} 

char getValidKey(const string& validKeys) 
{ 
    while (true) 
    { 
     const char key = readCharFromCin(); 
     if(isKeyValid(key, validKeys)) return letter; 

     cout << "Error. Invalid input.\n"; 
    } 
} 

對於第二種情況,避免break和簡單地ř eturn從你的switch。使包含switch的功能只做一件事。

string switchOperation(int myOperation) 
{ 
    switch (myOperation) 
    { 
     case 1: return "RIGHT"; 
     case 2: return "LEFT"; 
     case 3: return "CENTER_ONLY"; 
     case 4: return "CENTER_MISSING"; 
    } 

    return "Error. Invalid input."; 
} 

另外,儘量最大限度地const使用,並通過string情況下,你只能通過const&閱讀,以避免不必要的副本。

+0

+1,很好的重構成更小的函數。我擔心switchOperation的錯誤返回與普通字符串無法區分。 –

+0

@KennyOstrom:絕對是一個好點。返回類型應該是'variant ' - 我覺得這會讓答案太複雜,假設OP是初學者。 –

+0

或配對,或拋出異常(初學者也很難),但有一個更簡單的方法。bool getOperationDescription(int myOperation,std :: string&description);如果保持原樣,那麼我希望他用類似const std :: string INVALID_OPERATION的方式替換錯誤字符串(所以實際文本只能在一個地方,以防有人改變它)。 –