2014-10-07 16 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