简体   繁体   English

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

[英]Check if the input is a number or string in C++

I wrote the following code to check whether the input(answer3) is a number or string, if it is not a number it should return "Enter Numbers Only" but it returns the same even for numbers. 我写了下面的代码来检查输入(answer3)是一个数字还是字符串,如果它不是一个数字,它应该返回“仅输入数字”,但它返回相同的数字。 Please suggest me a solution. 请建议我一个解决方案。

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

}

If you're using C++98 , you can use stringstreams ( #include <sstream> ): 如果您使用的是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;
}

If boost is available to you , you can use lexical_cast ( #include <boost/lexical_cast.hpp> ): 如果你可以使用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;

If C++11 is available to you , you can use the builtin std::stoi function from <string> : 如果您可以使用C ++ 11,则可以使用<string>的builtin std::stoi 函数

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

OUTPUTS: 输出:

1234798797

You can use regex to do this: 您可以使用regex执行此操作:

#include <regex>

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

If you want to make isNumber() a generic function which can take any type of input: 如果你想让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;}

The above isNumber() function checks for integer only, double or float value with precision (which contains dot . ) will not return true. 上面的isNumber()函数只检查整数,精度的double或float值(包含dot . )不会返回true。 If you want precision too, then change the regex line to: 如果您也想要精度,那么将regex行更改为:

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

If you want a more efficient solution, see this one . 如果您想要更高效的解决方案,请参阅解决方案。

The function isdigit() is used to test for only digits ( 0,1,...,9) 函数isdigit()用于仅测试数字(0,1,...,9)

use this function to check for numbers 使用此功能检查数字

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

The input to isdigit is an integer value. isdigit的输入是一个整数值。 However, it will return true (non-zero) only if the value corresponds to '0'-'9'. 但是,仅当值对应于'0' - '9'时,它才会返回true(非零)。 If you convert them to integer values, they are 48-57. 如果将它们转换为整数值,则为48-57。 For all other values, isdigit will return false (zero). 对于所有其他值, isdigit将返回false(零)。

You can check whether you got an integer by changing checking logic: 您可以通过更改检查逻辑来检查是否有整数:

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

Another answer using strtod : 使用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) ;
}

To be able to handle any type of parameter use template: 为了能够处理任何类型的参数使用模板:

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

Note: 注意:

  1. White space will make it return false. 白色空间会使其返回虚假。
  2. NAN and INF will make it return false (to be exact, any character except valid exponent will make it return false). NANINF将使其返回false(确切地说,除有效指数之外的任何字符都将使其返回false)。 If you want to allow nan and inf , delete the || std::isalpha(s[0]) 如果要允许naninf ,请删除|| std::isalpha(s[0]) || std::isalpha(s[0]) part. || std::isalpha(s[0])部分。
  3. scientific form is allowed ie 1e+12 will return true. 允许科学形式,即1e + 12将返回true。
  4. Double/float or integer will return true. Double / float或integer将返回true。
  5. This is more efficient than the regex answer . 这比正则表达式的答案更有效。 (regex is heavy). (正则表达式很重)。

The interest phenomenon are the isdigit requires char to be cast to unsigned char . 兴趣现象是isdigit需要将char转换为unsigned char (Also see here ). (另见这里 )。

This is a somewhat old question, but I figured I'd add my own solution that I'm using in my code. 这是一个有点老问题,但我想我会在我的代码中添加自己的解决方案。

Another way to check if a string is a number is the std::stod function, which has been mentioned, but I use it a bit differently. 检查字符串是否为数字的另一种方法是std::stod函数,已经提到过,但我使用它有点不同。 In my use case, I use a try-catch block to check if the input is a string or number, like so with your code: 在我的用例中,我使用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;
}
...

The primary problem with this solution is that strings that begin with numbers (but aren't all numbers) will be converted to numbers. 此解决方案的主要问题是以数字(但不是所有数字)开头的字符串转换为数字。 This can be easily fixed by using std::to_string on the returned number and comparing it to the original string. 这可以通过在返回的数字上使用std::to_string并将其与原始字符串进行比较来轻松修复。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM