如果用户输入字符/字符串到 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);
}
在对
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);
}
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
是不好的编程习惯。通常最好使用适当的
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
是很有争议的。