繁体   English   中英

如何防止用户在 c++ 中输入字符串

[英]How to prevent the user from inputing a string in c++

您好,我对运算符重载比较陌生,但我确实相信它可以解决我在制作的几乎每个程序中都面临的问题。 我的目标是重载std::cin >> int_var以便它只能接受 integer 输入,如果它检测到输入了除 int 之外的输入,它会将用户置于循环中,直到输入为 int。

到目前为止,这就是我带给你的

#include <iostream>

std::istream& operator>> (std::istream& Cin, int *var)
{
  int var2;
  if(!Cin >> var2)
  {
    std::cout << "Invalid input!";
  }
  return Cin;
}

int main() {
  int var;
  std::cin >> var;
  std::cout << var;

}  

注意:此代码片段只是为了看看我是否可以检测到无效输入。 它还不需要它来包含循环。

获取用户输入的正确方法是:

  1. 读取一个字符串
  2. 尝试将字符串转换为 int (或其他)
  3. 如果转换失败,您应该:
    • 询问并再试一次,只有 IFF 用户被认为是人类
    • 终止(要求您的用户提供有效的输入)

这是因为用户总是在每次输入提示后按 Enter。

这个问题的变化比比皆是。 这是我的最后一个答案,并附有一个工作示例。

我不知道你能不能。 您需要做的是验证所有用户输入。 无论应用程序是什么,都永远不会信任用户。

所以你只需要检查你得到的值是否是一个 integer 然后你可以调用你的 function 如果它不是一个 integer 然后告诉他们为什么输入是错误的。

我不建议您尝试重载 stream 提取运算符>>以显着改变其行为。 创建自己的 function 会更有意义。

stream 提取将接受诸如"6sdfj23jlj"类的用户输入作为数字6的有效输入。 如果您想拒绝此类输入并在这种情况下重新提示用户输入新输入,那么使用面向行的输入(例如std::getline )而不是 stream 提取运算符>>可能更有意义。

使用std::getline读取字符串后,您可以尝试使用 function std::stoi

在下面的程序中,我创建了一个 function get_int_from_user ,它会反复询问用户输入,直到输入有效。

#include <iostream>
#include <string>

int get_int_from_user( const std::string &prompt )
{
    std::string line;
    std::size_t pos;
    int i;

    //repeat forever, until an explicit return statement or an
    //exception is thrown
    for (;;) //equivalent to while(1)
    {
        //prompt user for input
        std::cout << prompt;

        //attempt to read one line of input from user
        if ( !std::getline( std::cin, line ) )
        {
            throw std::runtime_error( "unexpected input error!\n" );
        }

        //attempt to convert string to integer
        try
        {
            i = std::stoi( line, &pos );
        }
        catch ( std::invalid_argument& )
        {
            std::cout << "Unable to convert input to number, try again!\n";
            continue;
        }
        catch ( std::out_of_range& )
        {
            std::cout << "Out of range error, try again!\n";
            continue;
        }

        //The remainder of the line is only allowed to contain
        //whitespace characters. The presence of any other
        //characters should cause the entire input to get rejected.
        //That way, input such as "6sdfj23jlj" will get rejected,
        //but input with trailing whitespace will still be accepted
        //(just like input with leading whitespace is accepted by
        //the function std::stoi).
        for ( ; pos < line.length(); pos++ )
        {
            if ( !std::isspace( static_cast<unsigned char>(line[pos]) ) )
            {
                std::cout << "Invalid character found, try again!\n";

                //we cannot use "continue" here, because that would
                //continue to the next iteration of the innermost
                //loop, but we want to continue to the next iteration
                //of the outer loop
                goto continue_outer_loop;
            }
        }

        //input is valid
        return i;

    continue_outer_loop:
        continue;
    }
}

int main()
{
    try
    {
        int i = get_int_from_user( "Please enter a number: " );

        std::cout << "Input was ok, you entered: " << i << '\n';
    }
    catch ( std::runtime_error& e )
    {
        std::cout << "Runtime error:" << e.what() << '\n';
    }
}

该程序具有以下行为:

Please enter a number: Test
Unable to convert input to number, try again!
Please enter a number: 3000000000
Out of range error, try again!
Please enter a number: 6sdfj23jlj
Invalid character found, try again!
Please enter a number: 633245183
Input was ok, you entered: 633245183

上面的代码使用了一个goto语句。 通常,如果可能,您不应该使用goto但是为了打破嵌套循环,它被认为是合适的

暂无
暂无

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

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