如何避免来自用户的错误输入?

时间:2021-02-22 06:47:36

I am a very newbie programmer, so I don't really know much about writing code to protect the application.. Basically, I created a basicMath.h file and created a do while loop to make a very basic console calculator (only two floats are passed through the functions). I use a series of if and else if statements to determine what the users wants to do. (1.add, 2.subtract, 3.multiply, 4.divide) I used a else { cout << "invalid input" << endl;} to protect against any other values, but then I tried to actually write a letter, and the program entered a infinite loop. Is there anyway to protect against users who accidentally hit a character instead of a number?

我是一个非常新手的程序员,所以我真的不太了解编写代码来保护应用程序。基本上,我创建了一个basicMath.h文件并创建了一个do while循环来制作一个非常基本的控制台计算器(只有两个浮点数)通过功能)。我使用一系列if和else if语句来确定用户想要做什么。 (1.add,2.subtract,3.multiply,4.divide)我使用了else {cout <<“无效输入”<< endl;}来防止任何其他值,但后来我试着写一封信,程序进入无限循环。无论如何要防止意外击中角色而不是数字的用户?

 `#include <iostream>
  #include "basicMath.h"

  using namespace std;
  char tryAgain = 'y';
  float numOne = 0, numTwo = 0;
  int options = 0;
  int main()
  {
   cout << "welcome to my calculator program." << endl;
 cout << "This will be a basic calculator." << endl;
 do{
    cout << "What would you like to do?" << endl;
    cout << "1. Addition." << endl;
    cout << "2. Subtraction." << endl;
    cout << "3. Multiplication" << endl;
    cout << "4. Division." << endl;
    cin >> options;
    if (options == 1){
        cout << "Enter your first number." << endl;
        cin >> numOne;
        cout << "Enter your second number." << endl;
        cin >> numTwo;
        cout << numOne << " + " << numTwo << " = " << add(numOne, numTwo) << endl;
    }
    else if (options == 2){
        cout << "Enter your first number." << endl;
        cin >> numOne;
        cout << "Enter your second number." << endl;
        cin >> numTwo;
        cout << numOne << " - " << numTwo << " = " << subtract(numOne, numTwo) << endl;
    }
    else if (options == 3){
        cout << "Enter your first number." << endl;
        cin >> numOne;
        cout << "Enter your second number." << endl;
        cin >> numTwo;
        cout << numOne << " * " << numTwo << " = " << multiply(numOne, numTwo) << endl;
    }
    else if (options == 4){
        cout << "Enter your first number." << endl;
        cin >> numOne;
        cout << "Enter your second number." << endl;
        cin >> numTwo;
        cout << numOne << " / " << numTwo << " = " << divide(numOne, numTwo) << endl;
    }
    else {
        cout << "Error, invalid option input." << endl;
    }
    cout << "Would you like to use this calculator again? (y/n)" << endl;
    cin >> tryAgain;
}while (tryAgain == 'y');
cout << "Thank you for using my basic calculator!" << endl;
return 0;
}
 `

3 个解决方案

#1


4  

One way would be to use exception handling, but as a newbie you're probably far from learning that.

一种方法是使用异常处理,但作为一个新手,你可能远没有学习它。

Instead use the cin.fail() which returns 1 after a bad or unexpected input. Note that you need to clear the "bad" status using cin.clear().

而是使用cin.fail(),它在输入错误或意外后返回1。请注意,您需要使用cin.clear()清除“坏”状态。

A simple way would be to implement a function:

一种简单的方法是实现一个功能:

int GetNumber ()
{
    int n;
    cin >> n;
    while (cin.fail())
    {
        cin.clear();
        cin.ignore();
        cout << "Not a valid number. Please reenter: ";
        cin >> n;
    }
    return n;
}

Now in your main function wherever you are taking input, just call GetNumber and store the returned value in your variable. For example, instead of cin >> numOne;, do numOne = GetNumber();

现在,在您的主函数中,无论您何时进行输入,只需调用GetNumber并将返回的值存储在变量中。例如,而不是cin >> numOne;,请执行numOne = GetNumber();

#2


0  

When you input to cin, it is expecting a specific type, such as an integer. If it receives something that it does not expect, such as a letter, it sets a bad flag.

输入cin时,它需要特定的类型,例如整数。如果收到它不期望的东西,例如字母,它会设置一个坏标志。

You can usually catch that by looking for fail, and if you find it, flush your input as well as the bad bit (using clear), and try again.

您通常可以通过查找失败来捕获它,如果找到它,请刷新输入和坏位(使用清除),然后重试。

#3


0  

Read a whole line of text first, then convert the line of text to a number and handle any errors in the string-to-number conversion.

首先读取整行文本,然后将文本行转换为数字并处理字符串到数字转换中的任何错误。

Reading a whole line of text from std::cin is done with the std::getline function (not to be confused with the stream's member function):

从std :: cin读取整行文本是使用std :: getline函数完成的(不要与流的成员函数混淆):

std::string line;
std::getline(std::cin, line);
if (!std::cin) {
    // some catastrophic failure
}

String-to-number conversion is done with std::istringstream (pre-C++11) or with std::stoi (C++11). Here is the pre-C++11 version:

使用std :: istringstream(pre-C ++ 11)或std :: stoi(C ++ 11)完成字符串到数字的转换。这是pre-C ++ 11版本:

std::istringstream is(line);
int number = 0;
is >> number;
if (!is) {
    // line is not a number, e.g. "abc" or "abc123", or the number is too big
    // to fit in an int, e.g. "11111111111111111111111111111111111"
} else if (!is.eof()) {
    // line is a number, but ends with a non-number, e.g. "123abc",
    // whether that's an error depends on your requirements
} else {
    // number is OK
}

And here the C++11 version:

这里是C ++ 11版本:

try {
    std::cout << std::stoi(line) << "\n";
} catch (std::exception const &exc) {
    // line is not a number, e.g. "abc" or "abc123", or the number is too big
    // to fit in an int, e.g. "11111111111111111111111111111111111"
    std::cout << exc.what() << "\n";
}

#1


4  

One way would be to use exception handling, but as a newbie you're probably far from learning that.

一种方法是使用异常处理,但作为一个新手,你可能远没有学习它。

Instead use the cin.fail() which returns 1 after a bad or unexpected input. Note that you need to clear the "bad" status using cin.clear().

而是使用cin.fail(),它在输入错误或意外后返回1。请注意,您需要使用cin.clear()清除“坏”状态。

A simple way would be to implement a function:

一种简单的方法是实现一个功能:

int GetNumber ()
{
    int n;
    cin >> n;
    while (cin.fail())
    {
        cin.clear();
        cin.ignore();
        cout << "Not a valid number. Please reenter: ";
        cin >> n;
    }
    return n;
}

Now in your main function wherever you are taking input, just call GetNumber and store the returned value in your variable. For example, instead of cin >> numOne;, do numOne = GetNumber();

现在,在您的主函数中,无论您何时进行输入,只需调用GetNumber并将返回的值存储在变量中。例如,而不是cin >> numOne;,请执行numOne = GetNumber();

#2


0  

When you input to cin, it is expecting a specific type, such as an integer. If it receives something that it does not expect, such as a letter, it sets a bad flag.

输入cin时,它需要特定的类型,例如整数。如果收到它不期望的东西,例如字母,它会设置一个坏标志。

You can usually catch that by looking for fail, and if you find it, flush your input as well as the bad bit (using clear), and try again.

您通常可以通过查找失败来捕获它,如果找到它,请刷新输入和坏位(使用清除),然后重试。

#3


0  

Read a whole line of text first, then convert the line of text to a number and handle any errors in the string-to-number conversion.

首先读取整行文本,然后将文本行转换为数字并处理字符串到数字转换中的任何错误。

Reading a whole line of text from std::cin is done with the std::getline function (not to be confused with the stream's member function):

从std :: cin读取整行文本是使用std :: getline函数完成的(不要与流的成员函数混淆):

std::string line;
std::getline(std::cin, line);
if (!std::cin) {
    // some catastrophic failure
}

String-to-number conversion is done with std::istringstream (pre-C++11) or with std::stoi (C++11). Here is the pre-C++11 version:

使用std :: istringstream(pre-C ++ 11)或std :: stoi(C ++ 11)完成字符串到数字的转换。这是pre-C ++ 11版本:

std::istringstream is(line);
int number = 0;
is >> number;
if (!is) {
    // line is not a number, e.g. "abc" or "abc123", or the number is too big
    // to fit in an int, e.g. "11111111111111111111111111111111111"
} else if (!is.eof()) {
    // line is a number, but ends with a non-number, e.g. "123abc",
    // whether that's an error depends on your requirements
} else {
    // number is OK
}

And here the C++11 version:

这里是C ++ 11版本:

try {
    std::cout << std::stoi(line) << "\n";
} catch (std::exception const &exc) {
    // line is not a number, e.g. "abc" or "abc123", or the number is too big
    // to fit in an int, e.g. "11111111111111111111111111111111111"
    std::cout << exc.what() << "\n";
}