C++ 如何确定字符串是否是带有C++;?

C++ 如何确定字符串是否是带有C++;?,c++,visual-c++,C++,Visual C++,我在尝试编写一个检查字符串是否为数字的函数时遇到了不少麻烦。对于我正在编写的游戏,我只需要检查我正在读取的文件中的一行是否是一个数字(这样我就知道它是否是一个参数)。我写了下面的函数,我相信它工作得很顺利(或者我无意中编辑了它以停止它,或者我有精神分裂症,或者Windows有精神分裂症): 你可以用Boo::C++语言来做C++的方式。如果你真的坚持不使用boost,你可以检查一下它的功能,然后去做。这很简单 try { double x = boost::lexical_cast<

我在尝试编写一个检查字符串是否为数字的函数时遇到了不少麻烦。对于我正在编写的游戏,我只需要检查我正在读取的文件中的一行是否是一个数字(这样我就知道它是否是一个参数)。我写了下面的函数,我相信它工作得很顺利(或者我无意中编辑了它以停止它,或者我有精神分裂症,或者Windows有精神分裂症):


你可以用Boo::C++语言来做C++的方式。如果你真的坚持不使用boost,你可以检查一下它的功能,然后去做。这很简单

try 
{
  double x = boost::lexical_cast<double>(str); // double could be anything with >> operator.
}
catch(...) { oops, not a number }
试试看
{
double x=boost::lexical_cast(str);//double可以是带有>>运算符的任何对象。
}
catch(…){oops,不是数字}

最有效的方法是迭代字符串,直到找到非数字字符。如果有任何非数字字符,则可以考虑字符串不是数字。< /P>
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();
}
或者,如果您想用C++11的方式来实现:

bool is_number(const std::string& s)
{
    return !s.empty() && std::find_if(s.begin(), 
        s.end(), [](unsigned char c) { return !std::isdigit(c); }) == s.end();
}

正如下面的评论所指出的,这只适用于正整数。如果您需要检测负整数或分数,您应该使用更健壮的基于库的解决方案。虽然,添加对负整数的支持非常简单。

在查阅了更多文档之后,我找到了一个支持我的需求的答案,但可能对其他人没有帮助。这里就是(没有恼人的返回true和返回false语句:-))


我建议使用正则表达式。与的完全正则表达式匹配(例如,使用)

将显示字符串是否为数字。这包括正数和负数、整数和小数

其他变化:

[0-9]+([\.][0-9]+)?
(只有正面)

(仅限整数)


(仅为正整数)

我只想加入使用迭代的想法,但其他一些代码会执行该迭代:

#include <string.h>

bool is_number(const std::string& s)
{
    return( strspn( s.c_str(), "-.0123456789" ) == s.size() );
}
#包括
bool是_编号(常数std::string&s)
{
返回(strspn(s.c_str(),“-.0123456789”)==s.size();
}
它不像检查小数点或减号时那样健壮,因为它允许在任何位置都有多个小数点或减号。好的是,它是一行代码,不需要第三方库


如果只允许使用正整数,则去掉“.”和“-”。

以下是检查正整数的解决方案:

bool isPositiveInteger(const std::string& s)
{
    return !s.empty() && 
           (std::count_if(s.begin(), s.end(), std::isdigit) == s.size());
}

为什么要重新发明轮子?C标准库(C++中也有)具有这样的功能:

char* p;
long converted = strtol(s, &p, 10);
if (*p) {
    // conversion failed because the input wasn't a number
}
else {
    // use converted
}
如果您想处理分数或科学记数法,请改为使用
strtod
(您将得到
double
结果)

如果希望允许使用C/C++样式的十六进制和八进制常量(
“0xABC”
),请改为使用最后一个参数
0

然后,您的函数可以写成

bool isParam(string line)
{
    char* p;
    strtol(line.c_str(), &p, 10);
    return *p == 0;
}

使用此解决方案,您可以检查从负数到正数甚至浮点数的所有内容。将
num
的类型更改为整数时,如果字符串包含点,则会出现错误

#include<iostream>
#include<sstream>
using namespace std;


int main()
{
      string s;

      cin >> s;

      stringstream ss;
      ss << s;

      float num = 0;

      ss >> num;

      if(ss.good()) {
          cerr << "No Valid Number" << endl;
      }
      else if(num == 0 && s[0] != '0') {
          cerr << "No Valid Number" << endl;
      }
      else {
          cout << num<< endl;
      }             
}
#包括
#包括
使用名称空间std;
int main()
{
字符串s;
cin>>s;
细流ss;
ss>num;
如果(ss.good()){

cerr对于C++11编译器,对于非负整数,我将使用如下内容(注意
而不是
std::
):


以下是使用
库执行此操作的另一种方法:

bool is_integer(const std::string & s){
    return std::regex_match(s, std::regex("[(-|+)|][0-9]+"));
}
布伦丹

bool isNumber(string line) 
{
    return (atoi(line.c_str())); 
}
差不多可以了

假设任何以0开头的字符串都是数字, 只需为这个案例添加一个检查

bool isNumber(const string &line) 
{
 if (line[0] == '0') return true;
 return (atoi(line.c_str()));
}
ofc“123hello”将像Tony D指出的那样返回true。

基于is的解决方案:

对于带有多个点或减号的字符串,它不稳定,但您可以删除这些字符,只检查整数


然而,我倾向于一种解决方案,基于在cstdlib中使用
strtod
查找十进制值、科学/工程符号、十六进制符号(C++11),甚至是INF/INFINITY/NAN(C++11)是:


几个月前,我实现了一种确定字符串是整数、十六进制还是双精度的方法

enum{
        STRING_IS_INVALID_NUMBER=0,
        STRING_IS_HEXA,
        STRING_IS_INT,
        STRING_IS_DOUBLE
};

bool isDigit(char c){
    return (('0' <= c) && (c<='9'));
}

bool isHexaDigit(char c){
    return ((('0' <= c) && (c<='9')) || ((tolower(c)<='a')&&(tolower(c)<='f')));
}


char *ADVANCE_DIGITS(char *aux_p){

    while(CString::isDigit(*aux_p)) aux_p++;
    return aux_p;
}

char *ADVANCE_HEXADIGITS(char *aux_p){

    while(CString::isHexaDigit(*aux_p)) aux_p++;
    return aux_p;
}


int isNumber(const string & test_str_number){
    bool isHexa=false;
    char *str = (char *)test_str_number.c_str();

    switch(*str){
    case '-': str++; // is negative number ...
               break;
    case '0': 
              if(tolower(*str+1)=='x')  {
                  isHexa = true;
                  str+=2;
              }
              break;
    default:
            break;
    };

    char *start_str = str; // saves start position...
    if(isHexa) { // candidate to hexa ...
        str = ADVANCE_HEXADIGITS(str);
        if(str == start_str)
            return STRING_IS_INVALID_NUMBER;

        if(*str == ' ' || *str == 0) 
            return STRING_IS_HEXA;

    }else{ // test if integer or float
        str = ADVANCE_DIGITS(str);
        if(*str=='.') { // is candidate to double
            str++;
            str = ADVANCE_DIGITS(str);
            if(*str == ' ' || *str == 0)
                return STRING_IS_DOUBLE;

            return STRING_IS_INVALID_NUMBER;
        }

        if(*str == ' ' || *str == 0)
            return STRING_IS_INT;

    }

    return STRING_IS_INVALID_NUMBER;


}

您可以意识到,如果未检测到数字,函数将返回0。0可以被视为false(类似于布尔值)。

我提出了一个简单的约定:

如果到ASCII的转换大于0或以0开头,则它是一个数字。它不是完美的,而是快速的

大概是这样的:

string token0;

if (atoi(token0.c_str())>0 || isdigit(token0.c_str()[0]) ) { //this is a value
    // do what you need to do...
}

我认为这个正则表达式应该处理几乎所有的情况

"^(\\-|\\+)?[0-9]*(\\.[0-9]+)?"
因此,您可以尝试以下可以同时使用的函数(Unicode和ANSI)


要检查字符串是否为数字、整数或浮点数,请使用:

 #include <sstream>

    bool isNumber(string str) {
    double d;
    istringstream is(str);
    is >> d;
    return !is.fail() && is.eof();
}
#包括
布尔isNumber(字符串str){
双d;
istringstream为(str);
is>>d;
return!is.fail()&&is.eof();
}
}

例2:

stringstream ss("011");
double my_number;
ss >> my_number; //my number = 11
例3:

stringstream ss("11ABCD");
double my_number;
ss >> my_number; //my number = 11 (even though there are letters after the 11)
对“垃圾”变量的解释:

为什么不检查提取到我的double中的值是否有效,如果有效,则返回true

请注意,即使输入字符串为“11ABCD”(不是数字),上面的示例3仍将成功地将数字11读入my_number变量

为了处理这种情况,我们可以对字符串变量(我称之为垃圾)进行另一次提取,该变量可以读取初始提取到double类型变量后字符串缓冲区中可能剩余的任何内容。如果剩余的内容将被读取到“垃圾”中,这意味着传入的完整字符串不是一个数字(它只是从一开始)在这种情况下,我们希望返回false

带前缀的“0”解释:

尝试将单个字符提取到双精度中会失败(将0返回到双精度中),但仍会将字符串缓冲区位置移到字符后面。在这种情况下,垃圾读取将为空,这将导致函数错误地执行
bool isNumber(const std::string& s)
{
   return !s.empty() && s.find_first_not_of("-.0123456789") == std::string::npos;
}
bool isNumberC(const std::string& s)
{
    char* p;
    strtod(s.c_str(), &p);
    return *p == 0;
}
enum{
        STRING_IS_INVALID_NUMBER=0,
        STRING_IS_HEXA,
        STRING_IS_INT,
        STRING_IS_DOUBLE
};

bool isDigit(char c){
    return (('0' <= c) && (c<='9'));
}

bool isHexaDigit(char c){
    return ((('0' <= c) && (c<='9')) || ((tolower(c)<='a')&&(tolower(c)<='f')));
}


char *ADVANCE_DIGITS(char *aux_p){

    while(CString::isDigit(*aux_p)) aux_p++;
    return aux_p;
}

char *ADVANCE_HEXADIGITS(char *aux_p){

    while(CString::isHexaDigit(*aux_p)) aux_p++;
    return aux_p;
}


int isNumber(const string & test_str_number){
    bool isHexa=false;
    char *str = (char *)test_str_number.c_str();

    switch(*str){
    case '-': str++; // is negative number ...
               break;
    case '0': 
              if(tolower(*str+1)=='x')  {
                  isHexa = true;
                  str+=2;
              }
              break;
    default:
            break;
    };

    char *start_str = str; // saves start position...
    if(isHexa) { // candidate to hexa ...
        str = ADVANCE_HEXADIGITS(str);
        if(str == start_str)
            return STRING_IS_INVALID_NUMBER;

        if(*str == ' ' || *str == 0) 
            return STRING_IS_HEXA;

    }else{ // test if integer or float
        str = ADVANCE_DIGITS(str);
        if(*str=='.') { // is candidate to double
            str++;
            str = ADVANCE_DIGITS(str);
            if(*str == ' ' || *str == 0)
                return STRING_IS_DOUBLE;

            return STRING_IS_INVALID_NUMBER;
        }

        if(*str == ' ' || *str == 0)
            return STRING_IS_INT;

    }

    return STRING_IS_INVALID_NUMBER;


}
string val; // the string to check if number...

switch(isNumber(val)){
   case STRING_IS_HEXA: 
   // use strtol(val.c_str(), NULL, 16); to convert it into conventional hexadecimal
   break;
   case STRING_IS_INT: 
   // use (int)strtol(val.c_str(), NULL, 10); to convert it into conventional integer
   break;
   case STRING_IS_DOUBLE:
   // use atof(val.c_str()); to convert it into conventional float/double
   break;
}
string token0;

if (atoi(token0.c_str())>0 || isdigit(token0.c_str()[0]) ) { //this is a value
    // do what you need to do...
}
"^(\\-|\\+)?[0-9]*(\\.[0-9]+)?"
bool IsNumber(CString Cs){
Cs.Trim();

#ifdef _UNICODE
std::wstring sr = (LPCWSTR)Cs.GetBuffer(Cs.GetLength());
return std::regex_match(sr, std::wregex(_T("^(\\-|\\+)?[0-9]*(\\.[0-9]+)?")));

#else
    std::string s = (LPCSTR)Cs.GetBuffer();
return std::regex_match(s, std::regex("^(\\-|\\+)?[0-9]*(\\.[0-9]+)?"));
#endif
}
 #include <sstream>

    bool isNumber(string str) {
    double d;
    istringstream is(str);
    is >> d;
    return !is.fail() && is.eof();
}
include <string>
bool validateDouble(const std::string & input) {
int decimals = std::count(input.begin(), input.end(), '.'); // The number of decimals in the string
int negativeSigns = std::count(input.begin(), input.end(), '-'); // The number of negative signs in the string

if (input.size() == decimals + negativeSigns) // Consists of only decimals and negatives or is empty
    return false;
else if (1 < decimals || 1 < negativeSigns) // More than 1 decimal or negative sign
    return false;
else if (1 == negativeSigns && input[0] != '-') // The negative sign (if there is one) is not the first character
    return false;
else if (strspn(input.c_str(), "-.0123456789") != input.size()) // The string contains a character that isn't in "-.0123456789"
    return false;
return true;
bool validateInt(const std::string & input) {
int negativeSigns = std::count(input.begin(), input.end(), '-'); // The number of negative signs in the string

if (input.size() == negativeSigns) // Consists of only negatives or is empty
    return false;
else if (1 < negativeSigns) // More than 1 negative sign
    return false;
else if (1 == negativeSigns && input[0] != '-') // The negative sign (if there is one) is not the first character
    return false;
else if (strspn(input.c_str(), "-0123456789") != input.size()) // The string contains a character that isn't in "-0123456789"
    return false;
return true;
bool validateUnsignedInt(const std::string & input) {
return (input.size() != 0 && strspn(input.c_str(), "0123456789") == input.size()); // The string is not empty and contains characters only in "0123456789"
bool isNumeric(string s){
    if ( !s.empty() && s[0] != '-' )
        s = "0" + s; //prepend 0

    string garbage;

    stringstream ss(s); 
    ss >> *(auto_ptr<double>(new double)) >> garbage;
/*
//the line above extracts the number into an anonymous variable. it could also be done like this:
double x;
ss >> x >> garbage;
*/
    //if there is no garbage return true or else return false
    return garbage.empty(); 
}
stringstream ss("11");
double my_number;
ss >> my_number; //my number = 11
stringstream ss("011");
double my_number;
ss >> my_number; //my number = 11
stringstream ss("11ABCD");
double my_number;
ss >> my_number; //my number = 11 (even though there are letters after the 11)
#include <regex>
bool isNumber( std::string token )
{
    return std::regex_match( token, std::regex( ( "((\\+|-)?[[:digit:]]+)(\\.(([[:digit:]]+)?))?" ) ) );
}
isNumber(const std::string &str) {    
  return !str.empty() && str.find_first_not_of("0123456789") == string::npos;
}
bool isNumber(string s) {
    if(s.size()==0) return false;
    for(int i=0;i<s.size();i++) {
        if((s[i]>='0' && s[i]<='9')==false) {
            return false;
        }
    }
    return true;
}
static const std::regex INT_TYPE("[+-]?[0-9]+");
static const std::regex UNSIGNED_INT_TYPE("[+]?[0-9]+");
static const std::regex DOUBLE_TYPE("[+-]?[0-9]+[.]?[0-9]+");
static const std::regex UNSIGNED_DOUBLE_TYPE("[+]?[0-9]+[.]?[0-9]+");

bool isIntegerType(const std::string& str_)
{
  return std::regex_match(str_, INT_TYPE);
}

bool isUnsignedIntegerType(const std::string& str_)
{
  return std::regex_match(str_, UNSIGNED_INT_TYPE);
}

bool isDoubleType(const std::string& str_)
{
  return std::regex_match(str_, DOUBLE_TYPE);
}

bool isUnsignedDoubleType(const std::string& str_)
{
  return std::regex_match(str_, UNSIGNED_DOUBLE_TYPE);
}
bool isNumeric(const std::string& string)
{
    std::size_t pos;
    long double value = 0.0;

    try
    {
        value = std::stold(string, &pos);
    }
    catch(std::invalid_argument&)
    {
        return false;
    }
    catch(std::out_of_range&)
    {
        return false;
    }

    return pos == string.size() && !std::isnan(value);
}
    bool isNumeric(string str)
    {
       stringstream stream;                   
       double number;

       stream<<str;
       stream>>number;

       return stream.eof();
    }
bool isNumber(const std::string &token)
{
    return std::regex_match(token, std::regex("(\\+|-)?[0-9]*(\\.?([0-9]+))$"));
}
bool AppUtilities::checkStringIsNumber(std::string s){
    //Eliminate obvious irritants that could spoil the party
    //Handle special cases here, e.g. return true for "+", "-", "" if they are acceptable as numbers to you
    if (s == "" || s == "." || s == "+" || s == "-" || s == "+." || s == "-.") return false;

    //Remove leading / trailing spaces **IF** they are acceptable to you
    while (s.size() > 0 && s[0] == ' ') s = s.substr(1, s.size() - 1);
    while (s.size() > 0 && s[s.size() - 1] == ' ') s = s.substr(0, s.size() - 1);


    //Remove any leading + or - sign
    if (s[0] == '+' || s[0] == '-')
        s = s.substr(1, s.size() - 1);

    //Remove decimal points
    long prevLength = s.size();

    size_t start_pos = 0;
    while((start_pos = s.find(".", start_pos)) != std::string::npos) 
        s.replace(start_pos, 1, "");

    //If the string had more than 2 decimal points, return false.
    if (prevLength > s.size() + 1) return false;

    //Check that you are left with numbers only!!
    //Courtesy selected answer by Charles Salvia above
    std::string::const_iterator it = s.begin();
    while (it != s.end() && std::isdigit(*it)) ++it;
    return !s.empty() && it == s.end();

    //Tada....
}
bool checkDigit(string str)
{  
   int n=str.length();

   for(int i=0;    i   < n ;   i++)
   {
     if(str[i]<'0' || str[i]>'9')
       return false;
   }

   return true;
}
int isdigits(const std::string & s)
{
    for (char c : s) if (!isdigit(c)) return (0);
    return (1);
}
bool is_number(const string& s, bool is_signed)
{
    if (s.empty()) 
        return false;

    auto it_begin = s.begin();
    if (is_signed && (s.front() == '+' || s.front() == '-'))
        ++it_begin;

    auto non_digit = std::find_if(it_begin, s.end(), [](const char& c) { return !std::isdigit(c); });
    return non_digit == s.end();
}