2014-02-16 194 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并将其与原始字符串进行比较,可以轻松修复此问题。

相关问题