【问题标题】:Check if the input is a number or string in C++检查输入是否是 C++ 中的数字或字符串
【发布时间】:2014-03-15 11:37:44
【问题描述】:

我编写了以下代码来检查 input(answer3) 是数字还是字符串,如果不是数字,则应返回“仅输入数字”,但即使对于数字,它也会返回相同的结果。请给我一个解决方案。

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

}

【问题讨论】:

  • 你键盘上的回车键有问题吗?空格键似乎也很狡猾
  • isdigit 将单个字符作为int,将其解释为 ASCII 字符,如果是数字字符('0' 到 '9',ASCII 48 到 57)则返回非零如果不是,则为零。它无法告诉您是否将整数读入answer3
  • 此外,cin &gt;&gt; someIntVariable 丢弃前导空格,读取可选符号(-+)后跟一系列数字,在第一个非数字字符处停止。因此,如果有人输入了无法解释的内容,它会将变量设置为 0。这就是 isdigit 后来失败的原因。
  • integer 上调用isdigit 是没有意义的,除非您准确知道整数成为数字意味着什么.

标签: c++ string integer user-input string-conversion


【解决方案1】:

您可以使用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() 函数仅检查整数、双精度或浮点值(包含点.)不会返回真。 如果您也想要精度,请将regex 行更改为:

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

如果您想要更高效的解决方案,请参阅this one

【讨论】:

    【解决方案2】:

    如果你使用的是 C++98,你可以使用stringstreams (#include &lt;sstream&gt;):

    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 &lt;boost/lexical_cast.hpp&gt;):

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

    如果您可以使用 C++11,您可以使用 &lt;string&gt; 中的内置 std::stoi function

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

    输出:

    1234798797
    

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 这不能用于十进制数。只能检查整数。
      • @jrd1: 没有双关语:)
      【解决方案4】:

      isdigit 的输入是一个整数值。但是,仅当值对应于“0”-“9”时,它才会返回真(非零)。如果将它们转换为整数值,它们是 48-57。对于所有其他值,isdigit 将返回 false(零)。

      你可以通过改变检查逻辑来检查你是否得到一个整数:

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

      【讨论】:

        【解决方案5】:

        使用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 更有效。 (正则表达式很重)。

        【讨论】:

          【解决方案6】:

          兴趣现象是isdigit要求char被转换为unsigned char。 (另见here)。

          【讨论】:

            【解决方案7】:

            这是一个有点老的问题,但我想我会添加我自己在我的代码中使用的解决方案。

            检查字符串是否为数字的另一种方法是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 并将其与原始字符串进行比较来轻松解决。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2022-01-10
              • 2013-01-25
              • 2011-07-22
              相关资源
              最近更新 更多