2014-02-16 264 views
5

我編寫了以下代碼來檢查輸入(answer3)是數字還是字符串,如果它不是數字,它應該返回「僅輸入數字」,但它會返回即使是數字也是如此。請給我一個解決方案。檢查輸入是否是C++中的數字或字符串

#include <iostream> 
#include <string> 
#include <typeinfo> 
#include <stdio.h> 
#include <stdlib.h> 
#include <ctype.h> 

using namespace std; 
int main() 
{ 

string ques1= "Client's Name :"; 
string ques2 = "Client's Address :"; 
string ques3 = "Mobile Number :"; 

char answer1 [80]; 
string answer2; 
int answer3; 

    cout<<ques1<<endl;  
    cin>>answer1;  

    cout<<ques2<<endl;  
    cin>>answer2; 

    cout<<ques3<<endl; 
    cin>>answer3; 

     if (isdigit(answer3)) 
     { 
       cout<<"Correct"<<endl;  

       } 

     else 
     { 
      cout<<"Enter Numbers Only"<<endl; 

      } 

system("pause>null"); 
return 0; 

} 
+5

鍵盤上的回車鍵有問題嗎? –

+1

'isdigit'將單個字符視爲int,將其解釋爲ASCII字符,如果是數字字符('0'至'9',ASCII 48至57),則返回非零值如果不是,則爲零。如果您將一個整數讀入'answer3',它無法告訴您。 –

+1

此外,'cin >> someIntVariable'丟棄前導空格,讀取一個可選符號('-'或'+'),後跟一串數字,停在第一個非數字字符處。所以如果有人輸入了一些無法解釋的東西,它會將變量設置爲0.這就是爲什麼'isdigit'稍後失敗的原因。 –

回答

6

如果您使用C++ 98,您可以使用stringstreams#include <sstream>):

std::string s = "1234798797"; 
std::istringstream iss(s); 

int num = 0; 

if (!(iss >> num).fail()) { 
    std::cout << num << std::endl; 
} 
else { 
    std::cerr << "There was a problem converting the string to an integer!" << std::endl; 
} 

如果升壓提供給您,你可以使用lexical_cast#include <boost/lexical_cast.hpp>) :

std::string s = "1234798797"; 
int num = boost::lexical_cast<int>(si);//num is 1234798797 
std::cout << num << std::endl; 

如果C++ 11是提供給您,可以使用內置的std::stoifunction<string>

std::string s = "1234798797"; 
int mynum = std::stoi(s); 
std::cout << mynum << std::endl; 

輸出:

1234798797 
2

函數ISDIGIT()被用於測試只有數字(0,1,...,9)

使用此功能檢查號碼

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

如果字符串包含小數點會發生什麼? – jrd1

+1

這不能用於十進制數字。只有整數可以被檢查。 –

+0

這正是我的觀點。 – jrd1

1

isdigit的輸入是一個整數值。但是,只有當值對應於'0' - '9'時,纔會返回true(非零)。如果你將它們轉換爲整數值,它們是48-57。對於所有其他值,isdigit將返回false(零)。

您可以檢查是否通過更改檢查邏輯得到了一個整數:

if (cin.fail()) 
{ 
    cout<<"Correct"<<endl;  
} 
else 
{ 
    cout<<"Enter Numbers Only"<<endl; 
} 
0

利息現象是isdigit要求char強制轉換爲unsigned char。 (另見here)。

5

您可以使用regex做到這一點:

#include <regex> 

bool isNumber(std::string x){ 
    std::regex e ("^-?\\d+"); 
    if (std::regex_match (x,e)) return true; 
    else return false;} 

如果你想isNumber()可以採取任何類型的輸入的通用功能:

#include <regex> 
#include <sstream> 

template<typename T> 
bool isNumber(T x){ 
    std::string s; 
    std::regex e ("^-?\\d+"); 
    std::stringstream ss; 
    ss << x; 
    ss >>s; 
    if (std::regex_match (s,e)) return true; 
    else return false;} 

以上isNumber()函數整數檢查只有具有精度的double或float值(包含點.)纔會返回true。 如果你想太精確,然後更改regex行:

std::regex e ("^-?\\d*\\.?\\d+"); 

如果你想有一個更有效的解決方案,請參閱this one

1

另一個答案使用strtod

bool isNumber(const std::string& s){ 
    if(s.empty() || std::isspace(s[0]) || std::isalpha(s[0])) return false ; 
    char * p ; 
    strtod(s.c_str(), &p) ; 
    return (*p == 0) ; 
} 

爲了能夠處理任何類型的參數使用模板:

#include <sstream> 

template<typename T> 
bool isNumber(T x){ 
    std::string s; 
    std::stringstream ss; 
    ss << x; 
    ss >>s; 
    if(s.empty() || std::isspace(s[0]) || std::isalpha(s[0])) return false ; 
    char * p ; 
    strtod(s.c_str(), &p) ; 
    return (*p == 0) ; 
} 

注:

  1. 空白將使其返回false。
  2. NANINF將使其返回false(確切地說,除有效指數之外的任何字符將使其返回false)。如果您想允許naninf,請刪除|| std::isalpha(s[0])部件。
  3. 允許科學形式,即1e + 12將返回true。
  4. Double/float或integer將返回true。
  5. 這比regex answer更有效率。 (正則表達式很重)。
0

這是一個有點老的問題,但我想我會添加我自己的解決方案,我在我的代碼中使用。

另一種檢查字符串是否是數字的方法是std::stod函數,這已經被提及,但我用它有點不同。在我的使用情況下,我使用try-catch塊來檢查,如果輸入的是一個字符串或數字,像這樣與您的代碼:

... 
try { 
    double n = stod(answer3); 
    //This will only be reached if the number was converted properly. 
    cout << "Correct" << endl; 
} catch (invalid_argument &ex) { 
    cout << "Enter Numbers Only" << endl; 
} 
... 

這種解決方案的主要問題是,以數字開頭的字符串(但不都是數字)轉換爲數字。通過在返回的號碼上使用std::to_string並將其與原始字符串進行比較,可以輕鬆修復此問題。

相關問題