2014-10-07 40 views
0

在這段代碼中,在a或b的一部分被製作後,菜單會出現兩次,我如何防止這種情況發生?我懷疑它與cin.get有關,可能從第一個cout語句捕獲空間。如果是這種情況,那麼解決方案將會消耗這個空間。我知道getline適用於字符串,但是這是一個char數據類型。也是一個快速相關的問題,是否有一段代碼,像getline(cin < < ws,stringName)對字符串,但對於char數據類型?如何防止開關功能中的菜單重複自身?

#include <iostream> 
#include <string> 
#include <cctype> 

using namespace std; 


void displayMenu(); 

int main() 
{ 
    char cSelection; 
    string sSelection; 

    //Create menu 
    const char OPTION_READING = 'A', OPTION_READINGTWO = 'B', OPTION_ENDING = 'C'; 

    do 
    { 
     displayMenu(); 
     cout << "\nPlease choose an option" << endl << endl; 
     cin.get(cSelection); 

     //respond to choice 
     switch (cSelection) 
     { 
     case OPTION_READING: 
     case 'a': 
      cout << "You picked 1" << endl; 
      break; 

     case OPTION_READINGTWO: 
     case 'b': 
      cout << "You picked 2" << endl; 
      break; 

     case OPTION_ENDING: 
     case 'c': 
      cout << "Thank you for using this program!"; 
      return 0; 

     default: 
      cout << cSelection << " " << "is an invalid choice"; 


     } 
    } while (toupper(sSelection[0] != OPTION_ENDING)); 


} 
void displayMenu() 
{ 

    cout << "\t \t \t" "Menu" << endl << endl; 
    cout << "A. Option 1\n"; 
    cout << "B. Option 2\n"; 
    cout << "C. Quit program"; 

} 
+0

它不是'cout'中的空間。它與您的菜單選擇字符一起輸入的換行符。以一種或另一種方式消費換行符。 – WhozCraig 2014-10-07 08:33:38

回答

1

廣場cin.get();cin.get(cSelection);後清除換行符。

1

#include <limits>

cin.get(cSelection); 

您可以添加:

std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); 
1

你額外的菜單命中是來自換行字符這仍然是在輸入流中的消耗。以任何方式消費它,其中之一如下所示。我也冒昧修復你的while條件,這個條件沒有被正確表達(你正在通過一個booltoupper,這顯然不是你想要的,同樣我將sSelection[0]的使用改爲cSelection 。由於這是,你會調用未定義行爲

#include <iostream> 
#include <string> 
#include <cctype> 
#include <limits> 
using namespace std; 

void displayMenu(); 

int main() 
{ 
    int cSelection; 
    string sSelection; 

    //Create menu 
    const char OPTION_READING = 'A', OPTION_READINGTWO = 'B', OPTION_ENDING = 'C'; 

    do 
    { 
     displayMenu(); 
     cout << "\nPlease choose an option" << endl << endl; 
     if ((cSelection = cin.get()) == EOF) 
      break; 

     // eat newline character 
     cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); 

     //respond to choice 
     switch (cSelection) 
     { 
      case OPTION_READING: 
      case 'a': 
       cout << "You picked 1" << endl; 
       break; 

      case OPTION_READINGTWO: 
      case 'b': 
       cout << "You picked 2" << endl; 
       break; 

      case OPTION_ENDING: 
      case 'c': 
       cout << "Thank you for using this program!\n"; 
       return 0; 

      default: 
       cout << cSelection << " " << "is an invalid choice"; 


     } 
    } while (std::toupper(static_cast<unsigned char>(cSelection)) != OPTION_ENDING); 


} 

void displayMenu() 
{ 
    cout << "\t \t \t" "Menu" << endl << endl; 
    cout << "A. Option 1\n"; 
    cout << "B. Option 2\n"; 
    cout << "C. Quit program"; 
} 

如何使用

cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');可能看起來有點神祕,但它確實是沒有那麼糟C++ 11提供了一個非常漂亮的模板類叫std::numeric_limits。給定一個數字類型,您可以觸發該類的靜態成員函數並獲取該類型的數字限制(最小值,最大值等)。每種母語類型都有該模板的大量專業化。我建議遵循我提供的鏈接並檢查它是如何工作的以及它提供的一切。

在我們的案例中,我們感興趣的是儘可能多地使用字符,直到我們到達換行符,這將被丟棄。我們使用輸入流std::cin中的ignore()方法來完成跳過。因此:

cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); 

有效地寫着「因爲你必須尋找一個新行跳過儘可能多的字符。如果你找到一個換行,跳過它,然後返回,你必須這樣做,如果需要的話最多EOF使用盡可能多的。 「。

它可能看起來有點神祕,但它並不罕見,而且相當有效。

無論如何,希望它有幫助。

+0

嘿WhozCraig一如既往的樂於助人!任何人,我都不願意改變這種狀況。你看到一個代碼給了我們去處理(在班級中沒有人完全理解,因爲我們甚至沒有涉及在while條件內處理那些參數的章節),因爲我不明白爲什麼有一個cSelection [0]我會假設它與原始非抽象內容中的其他內容有關。 謝謝大家 – ZeeZeeZee 2014-10-07 09:15:34

+0

@ZeeZeeZee寫道,雖然條件是很高的東西,因爲'toupper'不會用'bool'實現bo-diddly的惡魔。因爲它從來不是空字符,它總是*是真的。而且,由於代碼是現在,它也總是會調用未定義的行爲,因爲字符串是零長度的。如果你認爲硬退貨在退出選擇代碼中是一種後來的想法,事實並非如此。其原因是由於破碎的條件。無論如何,很高興它有幫助。 – WhozCraig 2014-10-07 09:25:31

+0

我把那部分放在那裏,因爲我認爲這是一個簡單/安全的退出循環的方式,坦率地說,我不知道參數字段中發生的情況。任何人,我有更多的問題要問。我會看看是否有類似的問題。 – ZeeZeeZee 2014-10-07 09:42:53