c++inputerror-handlinguser-inputformatted-input

Cin taking invalid input


I have a program that simply calculates the Ackermann function:

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

A majority of the code is checking for invalid input. For computational reasons, m cannot be larger than 3, and n cannot be larger than 12. It also checks if the input is negative.

Known problems:

How can I modify or fix my code so it only takes correct input?


Solution

  • I figured out a way to check if the input is something like 1.2.

    Instead of initializing m and n as integers, I can initialize them as doubles. Then I can check if the rounded double is the same as the initial double:

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

    Using this I can check if something like 1.2 is an integer or not. Then I can convert the double to an integer and continue on in the program.

    However, I am still unable to check for invalid inputs like 3z.