简体   繁体   English

如何在 C++ 中限制用户输入字符串和字符?

[英]How to limit user input in C++ for strings & characters?

I'm trying to create a small restaurant program in which I'll be practicing everything I learned in C++ so far.我正在尝试创建一个小型餐厅程序,我将在其中练习到目前为止我在 C++ 中学到的所有内容。 However I jumped into a small issue.但是我跳进了一个小问题。 At the beginning of the program, I prompt the user whether they want to enter the program, or leave it by choosing Y or N. If the input is anything other than that the program will tell the user is invalid.在程序开始时,我提示用户是否要进入程序,或者选择Y或N退出程序。如果输入的不是其他任何内容,程序会告诉用户无效。

The issue is lets say the user input one invalid character a.问题是假设用户输入了一个无效字符 a。 The invalid output will be displayed normally and everything seems perfect.无效的 output 将正常显示,一切看起来都很完美。 But if the user inputs two characters, or more, the invalid output case will be printed as many as the characters input by the user.但如果用户输入两个或更多字符,则无效的 output 案例将被打印与用户输入的字符一样多。 Sample below:下面的示例:

Output image Output 图像

#include <iostream>

int main()
{
    char ContinueAnswer;
    std::string Employee {"Lara"};
    std::cout << "\n\t\t\t---------------------------------------"
              << "\n\t\t\t|                                     |"    
              << "\n\t\t\t|            Welcome to OP            |"
              << "\n\t\t\t|Home to the best fast food in Orlando|"
              << "\n\t\t\t|                                     |"
              << "\n\t\t\t--------------------------------------|" << std::endl;

do
{
    std::cout << "\n\t\t\t    Would you like to enter? (Y/N)"
              << "\n\t\t\t                  "; std::cin >> ContinueAnswer;
    if(ContinueAnswer == 'y' || ContinueAnswer == 'Y')
    {
        system("cls");
        std::cout << "\n\t\t\t              My name is " << Employee << "."
                  << "\n\t\t\tI will assist you as we go through the menu." << std::endl;
    }
    else if(ContinueAnswer == 'n' || ContinueAnswer == 'N')
    {
        std::cout << "\t\t\t\tGoodbye and come again!" << std::endl;
        return 0;
    }
    else
        std::cout << "\n\t\t\t\t  Invalid Response" << std::endl;
}
while(ContinueAnswer != 'y' && ContinueAnswer != 'Y')

Thank you for taking time to read and for anyone who answers:)感谢您花时间阅读并感谢任何回答的人:)

You could simply make the user input a string :您可以简单地让用户输入一个string

std::string ContinueAnswer;

and compare like this:并像这样比较:

if(ContinueAnswer == "y" || ContinueAnswer == "Y")

which will handle multi-character inputs.它将处理多字符输入。

If you want to handle spaces in the input as well, change the:如果您还想处理输入中的空格,请更改:

std::cin >> ContinueAnswer;

to:至:

std::getline(std::cin, ContinueAnswer);

Before addressing your question I need to point out that you should always verify that the input was successful before doing anything with it.在解决您的问题之前,我需要指出,在对输入进行任何操作之前,您应该始终验证输入是否成功。 Processing variables which were not set due to the inout failing is a rather common source of errors.由于 inout 失败而未设置的处理变量是一个相当常见的错误来源。 For example:例如:

if (std::cin >> ContinueAnswer) {
    // do something with successfully read data
}
else {
    // deal with the input failing, e.g., bail out
}

I assume you consider everything on the same line to be invalid if nine of the expected characters was read.如果读取了九个预期字符,我假设您认为同一行上的所有内容都是无效的。 You could read a line into an std::string .可以将一行读入std::string However, that could be abused to provide an extremely long line of input which would eventually crash your program.但是,这可能会被滥用以提供极长的输入行,最终会使您的程序崩溃。 Also, reading data into a std::string just to throw it away seems ill-advised.此外,将数据读入std::string只是为了将其丢弃似乎是不明智的。 I'd recommend ignoring all characters up to and including a newline which could be done using (you need to include <limits> for this approach):我建议忽略所有字符,包括可以使用的换行符(您需要包含<limits>用于这种方法):

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

The first argument is a special value indicating that there may be an arbitrary amount of character before the newline.第一个参数是一个特殊值,表示在换行符之前可以有任意数量的字符。 In practice you could probably use a value like 1000 and it would be fine but it can be gamed.在实践中,您可能可以使用像 1000 这样的值,这很好,但它可以被玩弄。 Of course, in a real application a dedicated limit may be used to prevent an adversary to keep the program busy for long.当然,在实际应用中,可以使用专用限制来防止对手长时间保持程序繁忙。 I tend to assume my programs are under attack to make sure I deal with unusual cases.我倾向于假设我的程序受到攻击,以确保我处理不寻常的情况。

A quick refactor produces this:快速重构会产生以下结果:

#include <iostream>
#include <cstring>
#include <stdio.h>

int main()
{
        char ContinueAnswer[256];
        std::string Employee {"Lara"};
        std::cout << "\n\t\t\t---------------------------------------"
              << "\n\t\t\t|                                     |"
              << "\n\t\t\t|            Welcome to OP            |"
              << "\n\t\t\t|Home to the best fast food in Orlando|"
              << "\n\t\t\t|                                     |"
              << "\n\t\t\t--------------------------------------|" << std::endl;

        do
        {
            std::cout << "\n\t\t\t    Would you like to enter? (Y/N)"
                      << "\n\t\t\t                  "; std::cin.getline(ContinueAnswer,sizeof(ContinueAnswer));
            if(strcmp(ContinueAnswer, "Y") == 0 || strcmp(ContinueAnswer, "y") == 0)
            {
                system("cls");
                std::cout << "\n\t\t\t              My name is " << Employee << "."
                          << "\n\t\t\tI will assist you as we go through the menu." << std::endl;
            }
            else if(strcmp(ContinueAnswer, "N") == 0 || strcmp(ContinueAnswer, "n") == 0)
            {
                std::cout << "\t\t\t\tGoodbye and come again!" << std::endl;
                return 0;
            }
            else
                std::cout << "\n\t\t\t\t  Invalid Response" << std::endl; 
        }       
        while(true);
}

The cin.getline will get all characters until a delimiter. cin.getline 将获取所有字符,直到一个分隔符。 Then, you can check for equivalence using strcmp and reject anything other than what you want.然后,您可以使用 strcmp 检查等效性并拒绝除您想要的以外的任何内容。 Lastly, it seems like you are wanting this to be in an infinite loop, so don't worry about checking the input at the end and just loop back.最后,您似乎希望它处于无限循环中,所以不要担心最后检查输入并返回。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM