C++ 如何使用C++确定字符串是否为数字?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4654636/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 16:03:40  来源:igfitidea点击:

How to determine if a string is a number with C++?

c++visual-c++

提问by Brendan Weinstein

I've had quite a bit of trouble trying to write a function that checks if a string is a number. For a game I am writing I just need to check if a line from the file I am reading is a number or not (I will know if it is a parameter this way). I wrote the below function which I believe was working smoothly (or I accidentally edited to stop it or I'm schizophrenic or Windows is schizophrenic):

我在尝试编写一个检查字符串是否为数字的函数时遇到了很多麻烦。对于我正在编写的游戏,我只需要检查我正在读取的文件中的一行是否是数字(这样我就知道它是否是一个参数)。我编写了以下我认为运行顺利的函数(或者我不小心编辑以阻止它或者我是精神分裂症或 Windows 是精​​神分裂症):

bool isParam (string line)
{
    if (isdigit(atoi(line.c_str())))
        return true;

    return false;
}

回答by Charles Salvia

The most efficient way would be just to iterate over the string until you find a non-digit character. If there are any non-digit characters, you can consider the string not a number.

最有效的方法是遍历字符串,直到找到一个非数字字符。如果有任何非数字字符,您可以将字符串视为不是数字。

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

Or if you want to do it the C++11 way:

或者,如果您想以 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();
}

As pointed out in the comments below, this only works for positive integers. If you need to detect negative integers or fractions, you should go with a more robust library-based solution. Although, adding support for negative integers is pretty trivial.

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

回答by Ben Voigt

Why reinvent the wheel? The C standard library (available in C++ as well) has a function that does exactly this:

为什么要重新发明轮子?C 标准库(也可在 C++ 中使用)有一个函数可以做到这一点:

char* p;
long converted = strtol(s, &p, 10);
if (*p) {
    // conversion failed because the input wasn't a number
}
else {
    // use converted
}

If you want to handle fractions or scientific notation, go with strtodinstead (you'll get a doubleresult).

如果您想处理分数或科学记数法,请strtod改用(您会得到double结果)。

If you want to allow hexadecimal and octal constants in C/C++ style ("0xABC"), then make the last parameter 0instead.

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

Your function then can be written as

你的函数然后可以写成

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

回答by szx

With C++11 compiler, for non-negative integers I would use something like this (note the ::instead of std::):

使用 C++11 编译器,对于非负整数,我会使用这样的东西(注意::而不是std::):

bool is_number(const std::string &s) {
  return !s.empty() && std::all_of(s.begin(), s.end(), ::isdigit);
}

http://ideone.com/OjVJWh

http://ideone.com/OjVJWh

回答by Edward Strange

You can do it the C++ way with boost::lexical_cast. If you really insist on not using boost you can just examine what it does and do that. It's pretty simple.

您可以使用 boost::lexical_cast 以 C++ 方式来完成。如果你真的坚持不使用 boost,你可以检查它的作用并做到这一点。这很简单。

try 
{
  double x = boost::lexical_cast<double>(str); // double could be anything with >> operator.
}
catch(...) { oops, not a number }

回答by Mephane

I'd suggest a regex approach. A full regex-match (for example, using boost::regex) with

我建议使用正则表达式方法。完整的正则表达式匹配(例如,使用boost::regex

-?[0-9]+([.][0-9]+)?

would show whether the string is a number or not. This includes positive and negative numbers, integer as well as decimal.

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

Other variations:

其他变体:

[0-9]+([.][0-9]+)?

(only positive)

(只有正面)

-?[0-9]+

(only integer)

(仅整数)

[0-9]+

(only positive integer)

(仅正整数)

回答by David Rector

I just wanted to throw in this idea that uses iteration but some other code does that iteration:

我只是想提出这个使用迭代的想法,但其他一些代码会进行迭代:

#include <string.h>

bool is_number(const std::string& s)
{
    return( strspn( s.c_str(), "-.0123456789" ) == s.size() );
}

It's not robust like it should be when checking for a decimal point or minus sign since it allows there to be more than one of each and in any location. The good thing is that it's a single line of code and doesn't require a third-party library.

它不像检查小数点或减号时应有的那样健壮,因为它允许每个位置都有多个。好处是它是一行代码,不需要第三方库。

Take out the '.' and '-' if positive integers are all that are allowed.

取出'.' 和 '-' 如果所有正整数都是允许的。

回答by mpataki14

Here's another way of doing it using the <regex>library:

这是使用<regex>库的另一种方法:

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

回答by tzwickl

With this solution you can check everything from negative to positive numbers and even float numbers. When you change the type of numto integer you will get an error if the string contains a point.

使用此解决方案,您可以检查从负数到正数甚至浮点数的所有内容。当您将类型更改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;
      }             
}

Prove: C++ Program

证明:C++程序

回答by dk123

I've found the following code to be the most robust (c++11). It catches both integers and floats.

我发现以下代码是最健壮的(c++11)。它同时捕获整数和浮点数。

#include <regex>
bool isNumber( std::string token )
{
    return std::regex_match( token, std::regex( ( "((\+|-)?[[:digit:]]+)(\.(([[:digit:]]+)?))?" ) ) );
}

回答by Tomasz

Try this:

尝试这个:

isNumber(const std::string &str) {    
  return !str.empty() && str.find_first_not_of("0123456789") == string::npos;
}