如果两个数字输入不是整数,则返回错误

问题描述 投票:0回答:2

如果用户输入字符/字符串到 num1、num2,然后采取正确的输入,我试图使程序返回错误

我在互联网上搜索并找到了 cin.fail() 的解决方案,但它仅适用于第一个数字或根本不起作用

我被建议通过弄清楚变量的类型然后进行比较来做到这一点,但我无法弄清楚

如何在没有函数但循环的情况下以最简单的方式进行验证?

#include <iostream>
#include <fstream>
using namespace std;

int main () {

    int num1, num2; // two integers
    int choice; // chosen integers
    int ch1 = 0, ch2 = 0,ch3 = 0,ch4 = 0,ch5 = 0; // to keep track of chosen functions
    
    //const for choice of menu
    const int addition = 1,
              substruction = 2,
              multiplication = 3,
              division = 4, 
              modulo = 5,
              numberChange = 6;


    
    //intro
    cout << "This program has been made for arithmetic operations.\n";
    cout << "Please choose two  integers for arithmetic operations\n";
    cin >> num1 >> num2;


    do {
        cout << "Choose number of the operation you want to do\n";
        cout << "1. addition\n";
        cout << "2. subtraction\n";
        cout << "3. multiplication\n";
        cout << "4. division\n";
        cout << "5. modulo\n";
        cout << "6. CHANGE OF NUMBERS\n";
        cout << "To exit menu enter -1!\n";
        cin >> choice;

       

        switch (choice) {
            case 1:
            cout << "Result: " <<num1  << " + " << num2 << " = "<< num1 + num2 << endl;
            ch1++;
            break;
            case 2:
            cout << "Result: " <<num1  << " - " << num2 << " = "<< num1 - num2 << endl;
            ch2++;
            break;
            case 3: 
            cout << "Result: " <<num1  << " * " << num2 << " = "<<num1 * num2 << endl;
            ch3++;
            break;
            case 4:
            cout << "Result: " <<num1  << " / " << num2 << " = "<<num1 / num2 << endl;
            ch4++;
            break;
            case 5:
            cout << "Result: " <<num1  << " % " << num2 << " = "<<num1 % num2 << endl;
            ch5++;
            break;
            case 6:
            cout << "Okay, you can choose different numbers" << endl;
            cin >> num1 >> num2;
            break;
            case -1:

            ofstream myfile ("/Users/margaritakholostova/Desktop/us.txt");
            if (myfile.is_open())
             {
              myfile << "Addition was selected " << ch1 << " times\n";
              myfile << "Subtraction was selected " << ch2 << " times\n";
              myfile << "Multiplication was selected " << ch3 << " times\n";
              myfile << "Division was selected " << ch4 << " times\n";
              myfile << "Modulo was selected " << ch5 << " times\n";
              myfile.close();
            }
            else cout << "Unable to open file";
            return 0; 
            break;
        }

        //return error if input is not integer
        if (cin.fail()) {
            cout << "Error! Please put only integers!" << endl;
            cin.clear();
            cin.ignore(256, '\n');
            cin >> choice;
        }


        // validate the input for right number

        while (choice < addition || choice > numberChange )
        {
            if (choice != -1) {
                cout << "Please choose valid option out of menu (1-5)\n";
                cin >> choice;
            }
            
        }

    } while (choice != -1);        
}
c++ loops integer
2个回答
1
投票

在对

std::cin
返回的值进行操作之前,您需要检查 operator>>
的错误状态。尝试更多类似这样的事情:

#include <iostream> #include <fstream> #include <limits> using namespace std; int main () { int num1, num2; // two integers int choice; // chosen integers int ch1 = 0, ch2 = 0, ch3 = 0, ch4 = 0, ch5 = 0; // to keep track of chosen functions //const for choice of menu const int addition = 1, substruction = 2, multiplication = 3, division = 4, modulo = 5, numberChange = 6; //intro cout << "This program has been made for arithmetic operations.\n"; cout << "Please choose two integers for arithmetic operations\n"; //return error if input is not integers while (!(cin >> num1 >> num2)) { cin.clear(); cin.ignore(numeric_limits<streamsize>::max(), '\n'); cout << "Error! Please enter only integers!\n"; } do { cout << "Choose number of the operation you want to do\n"; cout << "1. addition\n"; cout << "2. subtraction\n"; cout << "3. multiplication\n"; cout << "4. division\n"; cout << "5. modulo\n"; cout << "6. CHANGE OF NUMBERS\n"; cout << "To exit menu enter -1!\n"; //return error if input is not integer while (!(cin >> choice)) { cin.clear(); cin.ignore(numeric_limits<streamsize>::max(), '\n'); cout << "Error! Please enter only integers!\n"; } // validate the input for right number switch (choice) { case 1: cout << "Result: " << num1 << " + " << num2 << " = " << num1 + num2 << '\n'; ch1++; break; case 2: cout << "Result: " << num1 << " - " << num2 << " = " << num1 - num2 << '\n'; ch2++; break; case 3: cout << "Result: " << num1 << " * " << num2 << " = " << num1 * num2 << '\n'; ch3++; break; case 4: cout << "Result: " << num1 << " / " << num2 << " = " << num1 / num2 << '\n'; ch4++; break; case 5: cout << "Result: " << num1 << " % " << num2 << " = " << num1 % num2 << '\n'; ch5++; break; case 6: cout << "Okay, you can choose different numbers\n"; while (!(cin >> num1 >> num2)) { cin.clear(); cin.ignore(numeric_limits<streamsize>::max(), '\n'); cout << "Error! Please enter only integers!\n"; } break; case -1: { ofstream myfile ("/Users/margaritakholostova/Desktop/us.txt"); if (myfile.is_open()) { myfile << "Addition was selected " << ch1 << " times\n"; myfile << "Subtraction was selected " << ch2 << " times\n"; myfile << "Multiplication was selected " << ch3 << " times\n"; myfile << "Division was selected " << ch4 << " times\n"; myfile << "Modulo was selected " << ch5 << " times\n"; myfile.close(); } else cout << "Unable to open file\n"; return 0; } default: cout << "Please choose a valid option from the menu (1-5)\n"; break; } } while (true); }
    

1
投票
线条

if ( cin.fail() ) { cout << "Error! Please put only integers!" << endl; cin.clear(); cin.ignore(256, '\n'); cin >> choice; }
将无法正常工作,因为在您执行流故障检查时,您已经使用了

的结果

cin >> num1 >> num2;

cin >> choice;

switch

 声明中。

因此,在

switch

 语句之前执行此类检查是有意义的。

另一方面,与其编写在每个输入操作后执行此类检查的代码,不如编写一个单独的函数

get_int_from_user

 读取一行输入并尝试将其转换为整数可能更有意义。如果此转换失败,则此函数应自动重新提示用户输入,直到转换成功。这样,您在主代码中所要做的就是调用函数 
get_int_from_user
,该函数将为您处理大部分输入验证。由于函数 
get_int_from_user
 保证返回一个有效的整数,因此您必须在主代码中执行的唯一输入验证是该整数是否在所需的范围内。这将使你的主要代码更容易编写。

另一个问题是进行范围检查更有意义

while (choice < addition || choice > numberChange ) { if (choice != -1) { cout << "Please choose valid option out of menu (1-5)\n"; cin >> choice; } }

switch

 语句内。这可以通过使用 
default
 标签轻松完成,如果值与任何 
case
 标签都不匹配,则会执行该标签。

在下面的代码片段中,我提供了问题的解决方案。但请注意,此解决方案使用三个

goto

 标签。通常应谨慎使用 goto
 语句,因为过度使用 
goto
 是不好的编程习惯。通常最好使用适当的 
for
while
do
 循环。然而,使用 
goto
 来打破嵌套循环 
通常被认为是合适的 。在我的解决方案中,无论如何我都需要两个 goto
 标签,以便打破嵌套循环。在这种情况下,我认为引入第三个 
goto
 标签并摆脱嵌套循环是合适的,因为它使代码更清晰。然而,由于大多数其他程序员可能会认为我的这个决定有争议,所以我在答案的末尾提供了一个替代解决方案,其中我从函数 
goto
 中删除了两个 
menu
 标签,以便只有函数
get_int_from_user
 使用 
goto
 标签,它严格用于打破嵌套循环。

这是我的解决方案,它使用三个

goto

 标签:

#include <iostream> #include <string> #include <stdexcept> #include <cctype> int get_int_from_user( const std::string& prompt ); void menu() { int num1, num2; int choice; int ch1 = 0, ch2 = 0, ch3 = 0, ch4 = 0, ch5 = 0; //intro std::cout << "This program has been made for arithmetic operations.\n"; new_numbers: std::cout << "Please choose two integers for arithmetic operations.\n"; num1 = get_int_from_user( "Please enter the first number: " ); num2 = get_int_from_user( "Please enter the second number: " ); menu: std::cout << "\n" "Choose number of the operation you want to do\n" "1. addition\n" "2. subtraction\n" "3. multiplication\n" "4. division\n" "5. modulo\n" "6. CHANGE OF NUMBERS\n" "To exit menu enter -1!\n" "\n"; choice = get_int_from_user( "Please enter your choice: " ); switch ( choice ) { case 1: std::cout << "\nResult: " <<num1 << " + " << num2 << " = " << num1 + num2 << "\n\n"; ch1++; goto menu; case 2: std::cout << "\nResult: " <<num1 << " - " << num2 << " = "<< num1 - num2 << "\n\n"; ch2++; goto menu; case 3: std::cout << "\nResult: " <<num1 << " * " << num2 << " = "<<num1 * num2 << "\n\n"; ch3++; goto menu; case 4: std::cout << "\nResult: " <<num1 << " / " << num2 << " = "<<num1 / num2 << "\n\n"; ch4++; goto menu; case 5: std::cout << "\nResult: " <<num1 << " % " << num2 << " = "<<num1 % num2 << "\n\n"; ch5++; goto menu; case 6: std::cout << "Okay, you can choose different numbers.\n" << '\n'; goto new_numbers; case -1: break; default: std::cout << "Please choose valid option out of menu (1-5)\n"; goto menu; } std::cout << "\n" << "Addition was selected " << ch1 << " times\n" << "Subtraction was selected " << ch2 << " times\n" << "Multiplication was selected " << ch3 << " times\n" << "Division was selected " << ch4 << " times\n" << "Modulo was selected " << ch5 << " times\n"; } int main() { try { menu(); } catch ( std::runtime_error& e ) { std::cout << "Runtime error: " << e.what() << '\n'; } } 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(true) { //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; } }
该程序具有以下行为:

This program has been made for arithmetic operations. Please choose two integers for arithmetic operations. Please enter the first number: 3 Please enter the second number: 4 Choose number of the operation you want to do 1. addition 2. subtraction 3. multiplication 4. division 5. modulo 6. CHANGE OF NUMBERS To exit menu enter -1! Please enter your choice: 1 Result: 3 + 4 = 7 Choose number of the operation you want to do 1. addition 2. subtraction 3. multiplication 4. division 5. modulo 6. CHANGE OF NUMBERS To exit menu enter -1! Please enter your choice: 2 Result: 3 - 4 = -1 Choose number of the operation you want to do 1. addition 2. subtraction 3. multiplication 4. division 5. modulo 6. CHANGE OF NUMBERS To exit menu enter -1! Please enter your choice: 3 Result: 3 * 4 = 12 Choose number of the operation you want to do 1. addition 2. subtraction 3. multiplication 4. division 5. modulo 6. CHANGE OF NUMBERS To exit menu enter -1! Please enter your choice: 4 Result: 3 / 4 = 0 Choose number of the operation you want to do 1. addition 2. subtraction 3. multiplication 4. division 5. modulo 6. CHANGE OF NUMBERS To exit menu enter -1! Please enter your choice: 5 Result: 3 % 4 = 3 Choose number of the operation you want to do 1. addition 2. subtraction 3. multiplication 4. division 5. modulo 6. CHANGE OF NUMBERS To exit menu enter -1! Please enter your choice: 6 Okay, you can choose different numbers. Please choose two integers for arithmetic operations. Please enter the first number: 5 Please enter the second number: 7 Choose number of the operation you want to do 1. addition 2. subtraction 3. multiplication 4. division 5. modulo 6. CHANGE OF NUMBERS To exit menu enter -1! Please enter your choice: 1 Result: 5 + 7 = 12 Choose number of the operation you want to do 1. addition 2. subtraction 3. multiplication 4. division 5. modulo 6. CHANGE OF NUMBERS To exit menu enter -1! Please enter your choice: 2 Result: 5 - 7 = -2 Choose number of the operation you want to do 1. addition 2. subtraction 3. multiplication 4. division 5. modulo 6. CHANGE OF NUMBERS To exit menu enter -1! Please enter your choice: 3 Result: 5 * 7 = 35 Choose number of the operation you want to do 1. addition 2. subtraction 3. multiplication 4. division 5. modulo 6. CHANGE OF NUMBERS To exit menu enter -1! Please enter your choice: 4 Result: 5 / 7 = 0 Choose number of the operation you want to do 1. addition 2. subtraction 3. multiplication 4. division 5. modulo 6. CHANGE OF NUMBERS To exit menu enter -1! Please enter your choice: 5 Result: 5 % 7 = 5 Choose number of the operation you want to do 1. addition 2. subtraction 3. multiplication 4. division 5. modulo 6. CHANGE OF NUMBERS To exit menu enter -1! Please enter your choice: -1 Addition was selected 2 times Subtraction was selected 2 times Multiplication was selected 2 times Division was selected 2 times Modulo was selected 2 times
由于使用了函数

get_int_from_user

,该程序还具有广泛的输入验证:

This program has been made for arithmetic operations. Please choose two integers for arithmetic operations. Please enter the first number: abc Unable to convert input to number, try again! Please enter the first number: 4abc Invalid character found, try again! Please enter the first number: 4 Please enter the second number:
这是已发布的函数 

menu

 的替代版本,其中两个 
goto
 标签都被删除并替换为循环和附加函数:

void input_two_numbers( int &i1, int &i2 ) { i1 = get_int_from_user( "Please enter the first number: " ); i2 = get_int_from_user( "Please enter the second number: " ); } void menu() { int num1, num2; int choice; int ch1 = 0, ch2 = 0, ch3 = 0, ch4 = 0, ch5 = 0; //intro std::cout << "This program has been made for arithmetic operations.\n"; std::cout << "Please choose two integers for arithmetic operations.\n"; input_two_numbers( num1, num2 ); for (;;) //infinite loop { std::cout << "\n" "Choose number of the operation you want to do\n" "1. addition\n" "2. subtraction\n" "3. multiplication\n" "4. division\n" "5. modulo\n" "6. CHANGE OF NUMBERS\n" "To exit menu enter -1!\n" "\n"; choice = get_int_from_user( "Please enter your choice: " ); switch ( choice ) { case 1: std::cout << "\nResult: " <<num1 << " + " << num2 << " = " << num1 + num2 << "\n\n"; ch1++; continue; case 2: std::cout << "\nResult: " <<num1 << " - " << num2 << " = "<< num1 - num2 << "\n\n"; ch2++; continue; case 3: std::cout << "\nResult: " <<num1 << " * " << num2 << " = "<<num1 * num2 << "\n\n"; ch3++; continue; case 4: std::cout << "\nResult: " <<num1 << " / " << num2 << " = "<<num1 / num2 << "\n\n"; ch4++; continue; case 5: std::cout << "\nResult: " <<num1 << " % " << num2 << " = "<<num1 % num2 << "\n\n"; ch5++; continue; case 6: std::cout << "Okay, you can choose different numbers.\n" << '\n'; input_two_numbers( num1, num2 ); continue; case -1: break; default: std::cout << "Please choose valid option out of menu (1-5)\n"; continue; } //break out of infinite loop break; } std::cout << "\n" << "Addition was selected " << ch1 << " times\n" << "Subtraction was selected " << ch2 << " times\n" << "Multiplication was selected " << ch3 << " times\n" << "Division was selected " << ch4 << " times\n" << "Modulo was selected " << ch5 << " times\n"; }
就个人而言,我更喜欢使用三个

goto

标签的版本。在我看来,必须创建一个附加函数并且必须重复调用该函数会使代码比简单地使用 
goto
 更难理解。但我确信许多其他程序员会不同意我的观点,因为使用 
goto
 是很有争议的。

© www.soinside.com 2019 - 2024. All rights reserved.