2016-09-22 61 views
0

我有一個程序,簡單地計算阿克曼功能:CIN服用無效的輸入

#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以1爲m,然後以n爲2。該計劃忽略了這段時間,並將其作爲兩個輸入,我想檢測這種無效輸入。

如何修改或修復我的代碼,以便它只需要正確的輸入?

+0

你能解釋一下你應該爲''3z''發生什麼? 「z」代表什麼? – nathanesau

+0

@nathanesau程序只能接受整數輸入。當輸入'3z'(或類似的)時,它忽略了'z'並且像'z'這樣不存在的'3'。從某種意義上說,我希望它能檢測到這樣一個無效的輸入(像'3z')。 – esote

回答

0

我想出了一種方法來檢查輸入是否像1.2

而不是初始化爲mn作爲整數,我可以將它們初始化爲雙打。然後,我可以檢查是否圓潤雙是一樣的初始雙:

double x; 

if(floor(x) != x){ 
    // not an integer 
} 

使用這個我可以檢查是否像1.2是一個整數或沒有。然後我可以將double轉換爲一個整數並在程序中繼續。

但是,我仍然無法檢查無效的輸入,如3z

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; 
}