C++ input validation

别来无恙 提交于 2021-02-07 18:01:59

问题


I am beginning C++ programming, and have to do a lot of input validation. I have found this function that seems universally applicable, but am having trouble with one aspect; If I were to type -90, the program doesn't give an error. my question(s) are: 1. How can I add the circumstance that input cannot be <= 0? 2. Is there a better way to limit users input? Maybe a library within C++?

Thank you for any help, or advice.

#include <ios>  // Provides ios_base::failure
#include <iostream>  // Provides cin

template <typename T>
T getValidatedInput()
{
    // Get input of type T
    T result;
    cin >> result;

    // Check if the failbit has been set, meaning the beginning of the input
    // was not type T. Also make sure the result is the only thing in the input
    // stream, otherwise things like 2b would be a valid int.
    if (cin.fail() || cin.get() != '\n')
    {
        // Set the error state flag back to goodbit. If you need to get the input
        // again (e.g. this is in a while loop), this is essential. Otherwise, the
        // failbit will stay set.
        cin.clear();

        // Clear the input stream using and empty while loop.
        while (cin.get() != '\n')
            ;

        // Throw an exception. Allows the caller to handle it any way you see fit
        // (exit, ask for input again, etc.)
        throw ios_base::failure("Invalid input.");
    }

    return result;
}

Usage

inputtest.cpp

#include <cstdlib>  // Provides EXIT_SUCCESS
#include <iostream>  // Provides cout, cerr, endl

#include "input.h"  // Provides getValidatedInput<T>()

int main()
{
    using namespace std;

    int input;

    while (true)
    {
        cout << "Enter an integer: ";

        try
        {
            input = getValidatedInput<int>();
        }
        catch (exception e)
        {
            cerr << e.what() << endl;
            continue;
        }

        break;
    }

    cout << "You entered: " << input << endl;

    return EXIT_SUCCESS;
}

回答1:


You can use functions to validate

template <typename T>
T getValidatedInput(function <bool(T)> validator) {
    T tmp;
    cin >> tmp;
    if (!validator(tmp)) {
        throw ios_base::failure("Invalid input.");
    }
    return tmp;
}

Usage

int input = getValidatedInput<int>([] (int arg) -> bool {
    return arg >= 0;
});



回答2:


std::istream::operator >> is defined in terms of strtol, strtoul, and cousins*, which unfortunately all invariably accept a minus sign even for unsigned types.

Essentially all you can do is accept signed int input and compare the result to zero. std::cin.setf( std::ios::failbit ) artificially raises a conversion exception, so you can sort-of emulate how the conversion function should behave on error, but that might not really be much help.

operator >> is defined in terms of std::num_get, which is defined in terms of scanf, which is defined in terms of strto*. Everyone just passed the buck, but strtoul is pretty surely defective.




回答3:


  1. Use unsigned int as a template parameter.
  2. Only you can setup a rules about what input is valid and what is not.



回答4:


I hope this is what you're after, it exit's upon entering zero, but will display negative numbers. It throws an exception error due to the input catch method.

#include "stdafx.h"
#include <iostream>

using namespace std;

void inputcatch()
{
    cin.clear();
    cin.ignore(cin.rdbuf()->in_avail());
}

int main()
{
    int input;
    bool quit = false;
    while (!quit)
    {
        cout << "Enter number" << endl;
        cin >> input;
        if (cin.fail())
        {
            inputcatch();
            cout << "incorrect input" << endl;
        }
        else if (input == 0)
        {
            quit = true;

        }
        else
        {
            cout << "your number: " << input << endl;
        }
    }
    return 0;
}


来源:https://stackoverflow.com/questions/25666047/c-input-validation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!