如何防止切换功能中的菜单重复出现?

时间:2014-10-07 08:13:14

标签: c++

在此代码中,菜单将在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";

}

3 个答案:

答案 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;

它可能看起来有点神秘,但它并不罕见,而且非常有效。

无论如何,希望它有所帮助。