在C++中检查输入是否为数字或字符串

8
我写了以下代码来检查输入(answer3)是一个数字还是字符串,如果它不是数字,应该返回"Enter Numbers Only",但即使是数字也返回相同的结果。请为我提供解决方案。
#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;  

}

8
你的键盘回车键有问题吗?空格键也似乎有点不灵。 - Ed Heal
1
isdigit 函数接受一个单字符作为 int,将其解释为 ASCII 字符,并返回非零值,如果它是数字字符('0' 到 '9',ASCII 48 到 57),否则返回零。它无法告诉你是否将整数读入到 answer3 中。 - Mike DeSimone
1
此外,cin >> someIntVariable 会忽略前导空格,读取一个可选符号 (-+) ,后跟一串数字,直到第一个非数字字符。因此,如果有人输入不能被解释的内容,它会将变量设置为0。这就是为什么稍后的 isdigit 会失败。 - Mike DeSimone
除非您确切知道整数是什么意思,否则在整数上调用 isdigit 没有任何意义。 - David Schwartz
7个回答

9
您可以使用“正则表达式”来完成此操作:
#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()函数只检查整数,带有精度的双精度或浮点值(包含小数点.)将不会返回true。 如果您也想要精度,请将regex行更改为:
std::regex e ("^-?\\d*\\.?\\d+");

如果您想要一个更高效的解决方案,请查看这个


7

如果你使用的是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;
}

如果您可以使用boost,您可以使用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,您可以使用来自<string>内置的std::stoi 函数

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

输出:

1234798797

4

函数 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();
}

1
这不能用于十进制数。只能检查整数。 - Chethan N
3
@jrd1: 没有双关语意图 :) - Ken Zein

2
isdigit的输入是整数值。然而,它只有在该值对应于'0'-'9'时才会返回true(非零)。如果将它们转换为整数值,则它们为48-57。对于所有其他值,isdigit将返回false(零)。
您可以通过更改检查逻辑来检查是否获得了整数:
if ( cin.fail() )
{
   cout<<"Correct"<<endl;     
}
else
{
   cout<<"Enter Numbers Only"<<endl;  
}

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. 双精度/浮点或整数将返回true。
  5. 这比正则表达式答案更有效率。(正则表达式很重)。

0

有趣的现象是,isdigit需要将char强制转换为unsigned char。(也可以参见这里)。


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并将其与原始字符串进行比较来轻松解决此问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接