我有一个简单计算Ackermann函数的程序:
#include <iostream>
// Ackermann function calculations
unsigned int ackermann(unsigned int m, unsigned int n){
if(m == 0)
return n+1;
if(n == 0)
return ackermann(m-1,1);
return ackermann(m-1,ackermann(m,n-1));
}
// Check for non-integer input
bool inputCheck(){
if(!std::cin.fail())
return false;
std::cout << "Invalid input!" << std::endl;
return true;
}
// Check for negative or overflow errors
bool numCheck(int i, char name){
if(i < 0){
std::cout << "Negative error!" << std::endl;
return true;
}
if(name == 'm' && i > 3){
std::cout << "Overflow error (m > 3)!" << std::endl;
return true;
}
if(name == 'n' && i > 12){
std::cout << "Overflow error (n > 12)!" << std::endl;
return true;
}
return false;
}
// Run input and num checks
bool check(int x, char y){
bool result = inputCheck() || numCheck(x, y);
std::cin.clear();
std::cin.ignore();
return result;
}
int main(){
int m, n;
bool valM, valN;
do{
std::cout << "m = ";
std::cin >> m;
valM = check(m, 'm');
} while(valM);
do{
std::cout << "n = ";
std::cin >> n;
valN = check(n, 'n');
} while(valN);
std::cout << "\nM = " << m << "\nN = " << n
<< "\n\nCALCULATING..." << std::endl;
std::cout << "A(" << m << ',' << n << ") = " << ackermann(m,n) << std::endl;
return 0;
}
大多数代码都在检查无效输入。出于计算原因,m
不能大于3,n
不能大于12.它还检查输入是否为负。
已知问题:
如果用户输入3z
之类的内容。 cin只取3并忽略z。显然,3z
与3
不同,我想检测到这样的无效输入。
如果用户输入1.2
之类的内容。 cin取m为1,然后n为n。程序忽略了句点并将其作为两个输入,我想检测这样一个无效的输入。
如何修改或修复我的代码,以便只接受正确的输入?
答案 0 :(得分:0)
答案 1 :(得分:0)
我建议读取字符串并将字符串转换为int。这样的事情会起作用。
#include <iostream>
#include <cctype>
#include <string>
// true is s is an int, false otherwise
bool is_number(const std::string& s)
{
std::string::const_iterator it = s.begin();
while (it != s.end() && std::isdigit(*it)) ++it;
return !s.empty() && it == s.end();
}
// Ackermann function calculations
unsigned int ackermann(unsigned int m, unsigned int n) {
if (m == 0)
return n + 1;
if (n == 0)
return ackermann(m - 1, 1);
return ackermann(m - 1, ackermann(m, n - 1));
}
// Check for non-integer input
bool inputCheck() {
if (!std::cin.fail())
return false;
std::cout << "Invalid input!" << std::endl;
return true;
}
// Check for negative or overflow errors
bool numCheck(int i, char name) {
if (i < 0) {
std::cout << "Negative error!" << std::endl;
return true;
}
if (name == 'm' && i > 3) {
std::cout << "Overflow error (m > 3)!" << std::endl;
return true;
}
if (name == 'n' && i > 12) {
std::cout << "Overflow error (n > 12)!" << std::endl;
return true;
}
return false;
}
// Run input and num checks
bool check(int x, char y) {
bool result = inputCheck() || numCheck(x, y);
std::cin.clear();
std::cin.ignore();
return result;
}
int main() {
std::string mstr, nstr; // parse int from string
int m, n;
bool valM, valN;
std::cout << "m = ";
std::getline(std::cin, mstr);
if (is_number(mstr))
{
m = atoi(mstr.c_str()); // now we have m as an int
}
valM = check(m, 'm');
std::cout << "n = ";
std::getline(std::cin, nstr);
if (is_number(nstr))
{
n = atoi(nstr.c_str()); // now we have n as an int
}
valN = check(n, 'n');
std::cout << "\nM = " << m << "\nN = " << n
<< "\n\nCALCULATING..." << std::endl;
std::cout << "A(" << m << ',' << n << ") = " << ackermann(m, n) << std::endl;
return 0;
}
答案 2 :(得分:0)
我找到了一种方法来检查输入是否类似于TextBox
。
我可以将它们初始化为双精度,而不是将1.2
和m
初始化为整数。然后我可以检查圆角双精度是否与初始双精度相同:
n
使用这个我可以检查double x;
if(floor(x) != x){
// not an integer
}
之类的东西是否是整数。然后我可以将double转换为整数并继续在程序中。
但是,我仍然无法检查1.2
之类的无效输入。