C++ C++;while循环洞察请求

C++ C++;while循环洞察请求,c++,C++,基本上,我在接近程序开始时的while循环中遇到了奇怪的问题,该循环检查用户对活动选择的验证。当他们选择并完成第一个活动时,它工作正常,但当他们完成第二个活动时,它将进入运行时,并不断请求用户输入有效的选项,即使他们甚至没有机会输入选项。有什么建议吗 #include <iostream> using namespace std; int main() { const int DIGITS_CHOICE = 1, IDENTIFIER_CHOICE = 2, DOUBLE

基本上,我在接近程序开始时的while循环中遇到了奇怪的问题,该循环检查用户对活动选择的验证。当他们选择并完成第一个活动时,它工作正常,但当他们完成第二个活动时,它将进入运行时,并不断请求用户输入有效的选项,即使他们甚至没有机会输入选项。有什么建议吗

#include <iostream>

using namespace std;

int main()
{
    const int DIGITS_CHOICE = 1, IDENTIFIER_CHOICE = 2, DOUBLE_CHOICE = 3, EXIT_CHOICE = 4;
    int choice;

    int userNumber, storedNumber, factor = 10, digitCounter = 0, subtractor;

    char ch;

    do
    {
        cout << "\n\n\t\tPlease choose an option:\n\n"
            << "1. How many digits?\n"
            << "2. Is this a valid C++ Identifer?\n"
            << "3. Is this a double letter word?\n"
            << "4. Exit\n";

        cout << endl << "Choice: ";
        cin >> choice;

        while (choice < DIGITS_CHOICE || choice > EXIT_CHOICE)
        {
            cout << endl << "Please enter a valid menu option: ";
            cin >> choice;
        }

        if (choice != EXIT_CHOICE)
        {
            switch (choice)
            {
            case DIGITS_CHOICE:
                cout << "Please enter an integer: ";
                cin >> userNumber;

                storedNumber = userNumber;

                if (userNumber < 10)
                {
                    digitCounter = 1;
                }
                else
                {
                    while (userNumber != 0)
                    {
                        subtractor = userNumber % factor;
                        if (subtractor > 0)
                        {
                            userNumber = userNumber - subtractor;
                            factor *= 10;
                            digitCounter++;
                        }
                        else
                        {
                            userNumber = 0;
                        }
                    }
                }

                cout << storedNumber << " has " << digitCounter << " digit(s)." << endl;
                factor = 10;
                digitCounter = 0;
                break;

            case IDENTIFIER_CHOICE:
                cout << "Please enter an identifier and press [Enter] immediately after.  ";

                cin >> ch;

                if (ch >= 0 || ch <= 9 || ch <= 'a' || ch >= 'z' || ch <= 'A' || ch >= 'Z' || ch != '_')
                {
                    if (ch >= 0 || ch <= 9)
                    {
                        cout << "Not a valid identifier." << endl;
                        cout << "Identifiers cannot start with a digit." << endl;
                        ch = '\n';
                    }
                    else
                    {
                        cout << "Not a valid identifier." << endl;
                        cout << "Inavlid character." << endl;
                        ch = '\n';
                    }
                }

                while (ch != '\n')
                {
                    if (ch >= 'a' || ch <= 'z' || ch >= 'A' || ch <= 'Z')
                    {
                        cin.get(ch);
                    }
                }
                break;
            case DOUBLE_CHOICE:
                break;
            }
        }

    } while (choice != EXIT_CHOICE);
    return 0;
}
#包括
使用名称空间std;
int main()
{
const int DIGITS_CHOICE=1,IDENTIFIER_CHOICE=2,DOUBLE_CHOICE=3,EXIT_CHOICE=4;
智力选择;
int userNumber,storedNumber,因子=10,数字计数器=0,减法器;
char ch;
做
{

cout您对有效字符的检查范围太广,没有意义:

if (ch >= 0 || ch <= 9 || ch <= 'a' || ch >= 'z' || ch <= 'A' || ch >= 'Z' || ch != '_')
现在还不清楚这之后的检查意味着什么?它仅仅意味着允许字母吗?在说“标识符不能以数字开头”之后,这似乎很奇怪。无论如何:


希望这能解决您的问题。

您对有效字符的检查范围太广,没有意义:

if (ch >= 0 || ch <= 9 || ch <= 'a' || ch >= 'z' || ch <= 'A' || ch >= 'Z' || ch != '_')
现在还不清楚这之后的检查意味着什么?它仅仅意味着允许字母吗?在说“标识符不能以数字开头”之后,这似乎很奇怪。无论如何:


希望这能解决您的问题。

逻辑不是很好;
i
是有效的,但您的代码说它不是。它至少可以返回菜单。您的代码的行为就像它会在键入字母时立即响应一样。事实并非如此。在用户按Enter键之前,它不会打印任何内容

问题似乎是您的变量
ch
char
。如果我键入任何长度超过一个字符的字符,将发生的情况是对单个字符求值,而我键入的其余字符仍保留在输入流中。看起来您正试图处理该问题,但它不起作用。我不去我不想花时间探究原因,部分原因是它很复杂,部分原因是我不知道istream行为的全部复杂性

我要说的是,如果您想处理多字符输入,请在任何地方使用cin.get(),而不仅仅是有时。您可以对每个字符进行处理,但在用户按Enter键之前,屏幕上不会显示任何内容

但这里的代码似乎是可行的:

#include <cctype>  // isalpha() and isalnum()
#include <string>  // ch is now a std::string
// ...
case IDENTIFIER_CHOICE:
    cout << "Please enter an identifier and press [Enter] immediately after.  ";

    std::cin.ignore(256, '\n');  // needed because of getline behavior
    std::getline(std::cin, ch);
    if (!(isalpha(ch[0]) || ch[0] == '_')) {
        cout << "Not valid.\n";
        break;
    }

    for (int i = 1; i < ch.size(); ++i) {
        if (!isalnum(ch[i])) {
            cout << "Not valid.\n";
            break;
        }
    }

    cout << "Valid.\n";
    break;
// ...
#包括//isalpha()和isalnum()
#include//ch现在是一个std::字符串
// ...
案例标识符\u选项:

cout逻辑不是很好;
i
是有效的,但你的代码说它不是。它至少可以返回菜单。你的代码的行为就像它会在键入字母时立即响应一样。事实并非如此。在用户按Enter键之前,它不会打印任何内容

问题似乎是您的变量
ch
char
。如果我键入任何长度超过一个字符的字符,将发生的情况是对单个字符求值,而我键入的其余字符仍保留在输入流中。看起来您正试图处理该问题,但它不起作用。我不去我不想花时间探究原因,部分原因是它很复杂,部分原因是我不知道istream行为的全部复杂性

我要说的是,如果您想处理多字符输入,请在任何地方使用cin.get(),而不仅仅是有时。您可以对每个字符进行处理,但在用户按Enter键之前,屏幕上不会显示任何内容

但这里的代码似乎是可行的:

#include <cctype>  // isalpha() and isalnum()
#include <string>  // ch is now a std::string
// ...
case IDENTIFIER_CHOICE:
    cout << "Please enter an identifier and press [Enter] immediately after.  ";

    std::cin.ignore(256, '\n');  // needed because of getline behavior
    std::getline(std::cin, ch);
    if (!(isalpha(ch[0]) || ch[0] == '_')) {
        cout << "Not valid.\n";
        break;
    }

    for (int i = 1; i < ch.size(); ++i) {
        if (!isalnum(ch[i])) {
            cout << "Not valid.\n";
            break;
        }
    }

    cout << "Valid.\n";
    break;
// ...
#包括//isalpha()和isalnum()
#include//ch现在是一个std::字符串
// ...
案例标识符\u选项:
库特
#include <cctype>  // isalpha() and isalnum()
#include <string>  // ch is now a std::string
// ...
case IDENTIFIER_CHOICE:
    cout << "Please enter an identifier and press [Enter] immediately after.  ";

    std::cin.ignore(256, '\n');  // needed because of getline behavior
    std::getline(std::cin, ch);
    if (!(isalpha(ch[0]) || ch[0] == '_')) {
        cout << "Not valid.\n";
        break;
    }

    for (int i = 1; i < ch.size(); ++i) {
        if (!isalnum(ch[i])) {
            cout << "Not valid.\n";
            break;
        }
    }

    cout << "Valid.\n";
    break;
// ...