2012-04-16 196 views
1

我對這個C++世界非常陌生,並且試圖爲數字密碼編寫一個輸入驗證函數。這是我到目前爲止:數字輸入的輸入驗證

#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(), '\n'); 
      cout << "Only 'numeric' value(s) are allowed: "; 
      continue; 
     } 

     // alpha-numeric entry also not allowed 
     cin.ignore(numeric_limits<streamsize>::max(), '\n'); 
     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; 
} 

它工作得很好,因爲不正確的值(s),但沒有在有效輸入時擺脫循環。任何想法我在這裏失蹤?乾杯!!從詹姆斯·觀世的劇本


錯誤:使用getline()審定幫我串 謝謝大家(尤其是詹姆斯甘孜)

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 


新的代碼出。這件事在這裏非常有用。

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

那裏有任何改善空間嗎?乾杯!!

+0

@Shahbaz我一直都知道我的C++是無望的,但不知道它已經那麼遠! – MacUsers 2012-04-16 17:53:49

+0

這不是關於你的代碼,你的問題標題讓我想起了我曾經看到過的這個有趣的事! – Shahbaz 2012-04-16 18:04:37

回答

2

這看起來像面向行的輸入。在這種情況下,通常的解決辦法是 使用getline

bool parseNumber(std::string const& text, int& results) 
{ 
    std::istringstream parser(text); 
    return parser >> results >> std::ws && parser.peek() == EOF; 
} 

int getNumber() 
{ 
    int results; 
    std::string line; 
    while (! std::getline(std::cin, line) || ! parseNumber(line, results)) 
    { 
     std::cin.clear(); 
     std::cout << "Only 'numeric' value(s) allowed:"; 
    } 
    return results; 
} 
+0

不是'getline()'缺少第二個參數嗎? – jrok 2012-04-16 18:11:00

+0

@James Kanze:它返回這個錯誤:'錯誤:變量'std :: istringstream分析器'具有初始化器但不完整類型' - 這是什麼意思?乾杯!! – MacUsers 2012-04-16 20:48:24

+0

@jrok是的。它應該是'std :: getline(std :: cin,line)'。 – 2012-04-17 07:54:33

2

如果有故障,然後轉換本身計算爲false流,所以你可以這樣做:

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

這實際上並沒有做我打算做的事情。像這樣的輸入:'123asd',應該被拒絕,但它接受'123'(如預期的那樣)。如果我輸入:'asd123',它什麼也不做。乾杯!! – MacUsers 2012-04-16 18:02:40

+0

如果用戶輸入''1abc'',將會成功。 – 2012-04-16 18:03:42

+0

@詹姆斯Kanze:這是我不想要的東西。我的目標是:除數字值之外的其他值應該被拒絕。乾杯!! – MacUsers 2012-04-16 18:11:06