Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
447 views
in Technique[技术] by (71.8m points)

c++ - input validation for numeric input

I'm very new to this C++ world and trying write a input validation function for numeric password. This is what I got so far:

#include <iostream>
#include <limits>
using namespace std;

void isNumeric(int &iN)
{
    while (1) {
        cin >> iN;

        if (cin.fail()) {
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '
');
            cout << "Only 'numeric' value(s) are allowed: ";
            continue;
        }

        // alpha-numeric entry also not allowed 
        cin.ignore(numeric_limits<streamsize>::max(), '
');
        if (cin.gcount() >  1) continue;

        // check against the -ve value
        if (iN <= 0 ) continue;

    break;
    }
}

int main()
{
    int x;

    cout << "Enter your number: ";
    isNumeric(x);
    cout << "You've entered: " << x << endl;

    return 0;
}

It's working just fine for incorrect value(s) but not breaking out of the loop upon valid entry. Any idea what I'm missing here? Cheers!!


ErroR from James Kanze's script:
test.cpp: In function ‘bool parseNumber(const string&, int&)’:
test.cpp:11:20: error: no match for ‘operator>>’ in ‘text >> results’
test.cpp:11:20: note: candidates are:
/usr/include/c++/4.6/bits/basic_string.tcc:998:5: note: template<class _CharT, class _Traits, class _Alloc> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, std::basic_string<_CharT, _Traits, _Alloc>&)
/usr/include/c++/4.6/bits/istream.tcc:957:5: note: template<class _CharT2, class _Traits2> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, _CharT2*)
/usr/include/c++/4.6/bits/istream.tcc:925:5: note: template<class _CharT, class _Traits> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, _CharT&)
/usr/include/c++/4.6/istream:709:5: note: template<class _Traits> std::basic_istream<char, _Traits>& std::operator>>(std::basic_istream<char, _Traits>&, unsigned char&)
/usr/include/c++/4.6/istream:714:5: note: template<class _Traits> std::basic_istream<char, _Traits>& std::operator>>(std::basic_istream<char, _Traits>&, signed char&)
/usr/include/c++/4.6/istream:756:5: note: template<class _Traits> std::basic_istream<char, _Traits>& std::operator>>(std::basic_istream<char, _Traits>&, unsigned char*)
/usr/include/c++/4.6/istream:761:5: note: template<class _Traits> std::basic_istream<char, _Traits>& std::operator>>(std::basic_istream<char, _Traits>&, signed char*)
test.cpp:11:42: error: ‘const string’ has no member named ‘peek’
test.cpp:11:52: error: ‘EOF’ was not declared in this scope


New code: using getline() and validation as a string Thanks everyone (especially James Kanze) for helping me out. This thing is pretty much working here.
void isNumeric( int &iN )
{
    string sN; 

    while (1) {
        getline(cin, sN);

        bool valNum = true;
        for ( unsigned iDx=0; iDx < sN.length(); iDx++ )
            if ( !isdigit(sN[iDx]) ) { 
                valNum = false;
                break;
            }   

        if ( !valNum ) { 
            cout << "Wrong entry; Try again: ";
            continue;
        }   

        stringstream sStream (sN );
        sStream >> iN; 

        if ( iN<=0 ) {
            cout << "Cannot be 0; Try again: "; 
            continue;
        }     
    break;   
    }   
}

Is there any room in there for any more improvement? Cheers!!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

If there is a failure to convert then the stream itself evaluates to false so you can do this:

int get_int() {
    int i;
    std::cout << "Please enter a number: " << std::endl;
    while(!(std::cin >> i)) {
        std::cin.clear();   //clear flags
        //discard bad input
        std::cin.ignore(std::numeric_limits<std::streamsize>::max()); 
        std::cout << "Incorrect, must be numeric: " << std::endl;
    }
    return i;
 }

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...