在此代码中,菜单将在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 :(得分:1)
在cin.get();
之后放置cin.get(cSelection);
以清除换行符。
答案 1 :(得分:1)
#include <limits>
后
cin.get(cSelection);
您可以添加:
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
答案 2 :(得分:1)
您的其他菜单匹配来自消费仍在输入流中的换行符。以任意多种方式消费,其中一种如下所示。我也冒昧地修复了while
条件,这个条件没有正确表达(你将bool
传递给toupper
,这显然不是你想要的。同样我改变了用法sSelection[0]
的{{1}},未在此代码中初始化为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');
有效地说&#34;跳过尽可能多的字符,你必须寻找换行符。如果找到换行符,请跳过它,然后返回。尽可能多地消耗,如果需要,可以使用EOF。&#34;
它可能看起来有点神秘,但它并不罕见,而且非常有效。
无论如何,希望它有所帮助。