C++ ISFloat函数

发布于 2025-01-31 13:32:49 字数 158 浏览 3 评论 0 原文

有人知道确定字符串值是否“符合”浮点数的方便手段?

bool IsFloat( string MyString )
{
   ... etc ...

   return ... // true if float; false otherwise
}

Does anybody know of a convenient means of determining if a string value "qualifies" as a floating-point number?

bool IsFloat( string MyString )
{
   ... etc ...

   return ... // true if float; false otherwise
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(20

同尘 2025-02-07 13:32:49

如果您无法使用Boost Library函数,则可以像这样编写自己的ISFLOAT函数。

#include <string>
#include <sstream>

bool isFloat( string myString ) {
    std::istringstream iss(myString);
    float f;
    iss >> noskipws >> f; // noskipws considers leading whitespace invalid
    // Check the entire string was consumed and if either failbit or badbit is set
    return iss.eof() && !iss.fail(); 
}

If you can't use a Boost library function, you can write your own isFloat function like this.

#include <string>
#include <sstream>

bool isFloat( string myString ) {
    std::istringstream iss(myString);
    float f;
    iss >> noskipws >> f; // noskipws considers leading whitespace invalid
    // Check the entire string was consumed and if either failbit or badbit is set
    return iss.eof() && !iss.fail(); 
}
删除→记忆 2025-02-07 13:32:49

您可能喜欢BOOST的LEXICAL_CAST(请参阅)。

bool isFloat(const std::string &someString)
{
  using boost::lexical_cast;
  using boost::bad_lexical_cast; 

  try
  {
    boost::lexical_cast<float>(someString);
  }
  catch (bad_lexical_cast &)
  {
    return false;
  }

  return true;
}

您可以使用ISTream避免需要增压,但是坦率地说,Boost太好了,无法遗漏。

You may like Boost's lexical_cast (see http://www.boost.org/doc/libs/1_37_0/libs/conversion/lexical_cast.htm).

bool isFloat(const std::string &someString)
{
  using boost::lexical_cast;
  using boost::bad_lexical_cast; 

  try
  {
    boost::lexical_cast<float>(someString);
  }
  catch (bad_lexical_cast &)
  {
    return false;
  }

  return true;
}

You can use istream to avoid needing Boost, but frankly, Boost is just too good to leave out.

如梦 2025-02-07 13:32:49

灵感来自这个答案我修改了该功能以检查字符串是否为浮点数。它不需要提升&amp;不依赖于弦乐失败 - 这只是简单的解析。

static bool isFloatNumber(const std::string& string){
    std::string::const_iterator it = string.begin();
    bool decimalPoint = false;
    int minSize = 0;
    if(string.size()>0 && (string[0] == '-' || string[0] == '+')){
      it++;
      minSize++;
    }
    while(it != string.end()){
      if(*it == '.'){
        if(!decimalPoint) decimalPoint = true;
        else break;
      }else if(!std::isdigit(*it) && ((*it!='f') || it+1 != string.end() || !decimalPoint)){
        break;
      }
      ++it;
    }
    return string.size()>minSize && it == string.end();
  }

IE

1
2.
3.10000
4.2f
-5.3f
+6.2f

被此功能正确识别为浮点。

1.0.0
2f
2.0f1

是非val浮标的示例。如果您不想识别格式x.xxf的浮点号,只需删除条件:

&& ((*it!='f') || it+1 != string.end() || !decimalPoint)

从第9行中删除。
如果您不想识别没有''的数字。作为float(即不是'1',只有'1.','1.0','1.0f'...),然后您可以将最后一行更改为:

return string.size()>minSize && it == string.end() && decimalPoint;

但是:有很多充分的理由使用boost的lexical_cast或使用弦线而不是这种“丑陋函数”的解决方案。但这使我可以更多地控制我想确切地识别为浮点数的格式(即小数点后的最大数字...)。

Inspired by this answer I modified the function to check if a string is a floating point number. It won't require boost & doesn't relies on stringstreams failbit - it's just plain parsing.

static bool isFloatNumber(const std::string& string){
    std::string::const_iterator it = string.begin();
    bool decimalPoint = false;
    int minSize = 0;
    if(string.size()>0 && (string[0] == '-' || string[0] == '+')){
      it++;
      minSize++;
    }
    while(it != string.end()){
      if(*it == '.'){
        if(!decimalPoint) decimalPoint = true;
        else break;
      }else if(!std::isdigit(*it) && ((*it!='f') || it+1 != string.end() || !decimalPoint)){
        break;
      }
      ++it;
    }
    return string.size()>minSize && it == string.end();
  }

I.e.

1
2.
3.10000
4.2f
-5.3f
+6.2f

is recognized by this function correctly as float.

1.0.0
2f
2.0f1

Are examples for not-valid floats. If you don't want to recognize floating point numbers in the format X.XXf, just remove the condition:

&& ((*it!='f') || it+1 != string.end() || !decimalPoint)

from line 9.
And if you don't want to recognize numbers without '.' as float (i.e. not '1', only '1.', '1.0', '1.0f'...) then you can change the last line to:

return string.size()>minSize && it == string.end() && decimalPoint;

However: There are plenty good reasons to use either boost's lexical_cast or the solution using stringstreams rather than this 'ugly function'. But It gives me more control over what kind of formats exactly I want to recognize as floating point numbers (i.e. maximum digits after decimal point...).

晨敛清荷 2025-02-07 13:32:49

我最近写了一个功能来检查字符串是否为数字。这个数字可以是整数或浮点。

您可以扭转我的代码并添加一些单元测试。

bool isNumber(string s)
{
    std::size_t char_pos(0);

    // skip the whilespaces
    char_pos = s.find_first_not_of(' ');
    if (char_pos == s.size()) return false;


    // check the significand
    if (s[char_pos] == '+' || s[char_pos] == '-') ++char_pos; // skip the sign if exist

    int n_nm, n_pt;
    for (n_nm = 0, n_pt = 0; std::isdigit(s[char_pos]) || s[char_pos] == '.'; ++char_pos) {
        s[char_pos] == '.' ? ++n_pt : ++n_nm;
    }
    if (n_pt>1 || n_nm<1) // no more than one point, at least one digit
        return false;

    // skip the trailing whitespaces
    while (s[char_pos] == ' ') {
        ++ char_pos;
    }

    return char_pos == s.size();  // must reach the ending 0 of the string
}


void UnitTest() {
    double num = std::stod("825FB7FC8CAF4342");
    string num_str = std::to_string(num);

    // Not number
    assert(!isNumber("1a23"));
    assert(!isNumber("3.7.1"));
    assert(!isNumber("825FB7FC8CAF4342"));
    assert(!isNumber(" + 23.24"));
    assert(!isNumber(" - 23.24"));

    // Is number
    assert(isNumber("123"));
    assert(isNumber("3.7"));
    assert(isNumber("+23.7"));
    assert(isNumber("  -423.789"));
    assert(isNumber("  -423.789    "));
}

I recently wrote a function to check whether a string is a number or not. This number can be an Integer or Float.

You can twist my code and add some unit tests.

bool isNumber(string s)
{
    std::size_t char_pos(0);

    // skip the whilespaces
    char_pos = s.find_first_not_of(' ');
    if (char_pos == s.size()) return false;


    // check the significand
    if (s[char_pos] == '+' || s[char_pos] == '-') ++char_pos; // skip the sign if exist

    int n_nm, n_pt;
    for (n_nm = 0, n_pt = 0; std::isdigit(s[char_pos]) || s[char_pos] == '.'; ++char_pos) {
        s[char_pos] == '.' ? ++n_pt : ++n_nm;
    }
    if (n_pt>1 || n_nm<1) // no more than one point, at least one digit
        return false;

    // skip the trailing whitespaces
    while (s[char_pos] == ' ') {
        ++ char_pos;
    }

    return char_pos == s.size();  // must reach the ending 0 of the string
}


void UnitTest() {
    double num = std::stod("825FB7FC8CAF4342");
    string num_str = std::to_string(num);

    // Not number
    assert(!isNumber("1a23"));
    assert(!isNumber("3.7.1"));
    assert(!isNumber("825FB7FC8CAF4342"));
    assert(!isNumber(" + 23.24"));
    assert(!isNumber(" - 23.24"));

    // Is number
    assert(isNumber("123"));
    assert(isNumber("3.7"));
    assert(isNumber("+23.7"));
    assert(isNumber("  -423.789"));
    assert(isNumber("  -423.789    "));
}
梦途 2025-02-07 13:32:49

我一直喜欢 strtof ,因为它可以指定最终指针。

bool isFloat(const std::string& str)
{
    char* ptr;
    strtof(str.c_str(), &ptr);
    return (*ptr) == '\0';
}

之所以起作用,是因为最终指针指向解析开始失败的角色,因此,如果指向NUL末端,则将整个字符串作为浮子解析。

我想,在十年中,没有人提到这种方法已经存在,我想这是因为它更像是 c风格这样做的方法。但是,它在C ++中仍然完全有效,并且比任何流解决方案都更优雅。此外,它与“+inf”“ -inf”等一起使用,依此类推,而忽略了领先的空格。

编辑

不要被空字符串所吸引,否则最终指针将处于nul终止上(因此返回true)。以上代码应为:

bool isFloat(const std::string& str)
{
    if (str.empty())
        return false;

    char* ptr;
    strtof(str.c_str(), &ptr);
    return (*ptr) == '\0';
}

I always liked strtof since it lets you specify an end pointer.

bool isFloat(const std::string& str)
{
    char* ptr;
    strtof(str.c_str(), &ptr);
    return (*ptr) == '\0';
}

This works because the end pointer points to the character where the parse started to fail, therefore if it points to a nul-terminator, then the whole string was parsed as a float.

I'm surprised no one mentioned this method in the 10 years this question has been around, I suppose because it is more of a C-Style way of doing it. However, it is still perfectly valid in C++, and more elegant than any stream solutions. Also, it works with "+inf" "-inf" and so on, and ignores leading whitespace.

EDIT

Don't be caught out by empty strings, otherwise the end pointer will be on the nul-termination (and therefore return true). The above code should be:

bool isFloat(const std::string& str)
{
    if (str.empty())
        return false;

    char* ptr;
    strtof(str.c_str(), &ptr);
    return (*ptr) == '\0';
}
仙气飘飘 2025-02-07 13:32:49

[编辑:固定在禁止的初始空间和尾随的废话。]

#include <sstream>

bool isFloat(string s) {
    istringstream iss(s);
    float dummy;
    iss >> noskipws >> dummy;
    return iss && iss.eof();     // Result converted to bool
}

您可以轻松地将其转换为类型 t 而不是 float 。从本质上讲,这就是boost的 lexical_cast

[EDIT: Fixed to forbid initial whitespace and trailing nonsense.]

#include <sstream>

bool isFloat(string s) {
    istringstream iss(s);
    float dummy;
    iss >> noskipws >> dummy;
    return iss && iss.eof();     // Result converted to bool
}

You could easily turn this into a function templated on a type T instead of float. This is essentially what Boost's lexical_cast does.

半枫 2025-02-07 13:32:49

快速而肮脏的解决方案使用 a>:

bool isFloat(const std::string& s) {
    try {
        std::stof(s);
        return true;
    } catch(...) {
        return false;
    }
}

Quick and dirty solution using std::stof:

bool isFloat(const std::string& s) {
    try {
        std::stof(s);
        return true;
    } catch(...) {
        return false;
    }
}
泛滥成性 2025-02-07 13:32:49

我想您想在输入字符串上运行正则匹配。我认为测试所有边缘案例可能相当复杂。

此站点有一些很好的信息。如果您只想跳到最后,则说:
^[ - +]?[0-9]*\。?[0-9]+([ee] [ - +]?[0-9]+)?$

如果您理解,哪个基本上是有道理的正则语法。

I'd imagine you'd want to run a regex match on the input string. I'd think it may be fairly complicated to test all the edge cases.

This site has some good info on it. If you just want to skip to the end it says:
^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$

Which basically makes sense if you understand regex syntax.

[旋木] 2025-02-07 13:32:49

使用C ++ 17:

bool isNumeric(std::string_view s)
{
    double val;
    auto [p, ec] = std::from_chars(s.data(), s.data() + s.size(), val);
    return ec == std::errc() && p == s.data() + s.size();
}

返回两次检查都是必要的。第一个检查没有溢出或其他错误。第二个检查整个字符串是否已读取。

With C++17:

bool isNumeric(std::string_view s)
{
    double val;
    auto [p, ec] = std::from_chars(s.data(), s.data() + s.size(), val);
    return ec == std::errc() && p == s.data() + s.size();
}

Both checks on return are necessary. The first checks that there are no overflow or other errors. The second checks that the entire string was read.

_畞蕅 2025-02-07 13:32:49

您可以使用中描述的方法在c ++?中,而不是扔 conversion_error ,返回 false (指示字符串不代表 float )和 true 否则。

You can use the methods described in How can I convert string to double in C++?, and instead of throwing a conversion_error, return false (indicating the string does not represent a float), and true otherwise.

桃扇骨 2025-02-07 13:32:49
int isFloat(char *s){
  if(*s == '-' || *s == '+'){
    if(!isdigit(*++s)) return 0;
  }
  if(!isdigit(*s)){return 0;}
  while(isdigit(*s)) s++;
  if(*s == '.'){
    if(!isdigit(*++s)) return 0;
  }
  while(isdigit(*s)) s++;
  if(*s == 'e' || *s == 'E'){
    s++;
    if(*s == '+' || *s == '-'){
        s++;
        if(!isdigit(*s)) return 0;
    }else if(!isdigit(*s)){
        return 0;
    }
  }
  while(isdigit(*s)) s++;
  if(*s == '\0') return 1;
  return 0;
}
int isFloat(char *s){
  if(*s == '-' || *s == '+'){
    if(!isdigit(*++s)) return 0;
  }
  if(!isdigit(*s)){return 0;}
  while(isdigit(*s)) s++;
  if(*s == '.'){
    if(!isdigit(*++s)) return 0;
  }
  while(isdigit(*s)) s++;
  if(*s == 'e' || *s == 'E'){
    s++;
    if(*s == '+' || *s == '-'){
        s++;
        if(!isdigit(*s)) return 0;
    }else if(!isdigit(*s)){
        return 0;
    }
  }
  while(isdigit(*s)) s++;
  if(*s == '\0') return 1;
  return 0;
}
尛丟丟 2025-02-07 13:32:49

其他响应的主要问题是性能

通常,您不需要每个角案件,例如Nan和 - /+ Inf,覆盖速度并不像具有速度那样重要。也许您不需要处理1.0E+03符号。您只需要一种快速将字符串解析为数字的方法。

这是一个简单,纯净的std :: string方法,这不是很快:

size_t npos = word.find_first_not_of ( ".+-0123456789" );
if ( npos == std::string::npos ) {
   val = atof ( word.c_str() );
}

这很慢,因为它是o(k*13),检查每个字符对0 thur 9,

这是一种更快的方法:

bool isNum = true;
int st = 0;
while (word.at(st)==32) st++;    // leading spaces
ch = word.at(st);
if (ch == 43 || ch==45 ) st++;   // check +, -

for (int n = st; n < word.length(); n++) {
  char ch = word.at(n);
  if ( ch < 48 || ch > 57 || ch != 46 ) {
     isNum = false;
     break;   // not a num, early terminate
  } 
}

这是一种提早终止的好处如果找到任何任何非数字字符,并且按范围进行检查,而不是每个数字数字(0-9)。因此,平均比较为每个char,o(k*3),与提前终止。

请注意,此技术与stdlib“ atof”函数中使用的技术非常相似:

The main issue with other responses is performance

Often you don't need every corner case, for example maybe nan and -/+ inf, are not as important to cover as having speed. Maybe you don't need to handle 1.0E+03 notation. You just want a fast way to parse strings to numbers.

Here is a simple, pure std::string way, that's not very fast:

size_t npos = word.find_first_not_of ( ".+-0123456789" );
if ( npos == std::string::npos ) {
   val = atof ( word.c_str() );
}

This is slow because it is O(k*13), checking each char against 0 thur 9

Here is a faster way:

bool isNum = true;
int st = 0;
while (word.at(st)==32) st++;    // leading spaces
ch = word.at(st);
if (ch == 43 || ch==45 ) st++;   // check +, -

for (int n = st; n < word.length(); n++) {
  char ch = word.at(n);
  if ( ch < 48 || ch > 57 || ch != 46 ) {
     isNum = false;
     break;   // not a num, early terminate
  } 
}

This has the benefit of terminating early if any non-numerical character is found, and it checks by range rather than every number digit (0-9). So the average compares is 3x per char, O(k*3), with early termination.

Notice this technique is very similar to the actual one used in the stdlib 'atof' function:
http://www.beedub.com/Sprite093/src/lib/c/stdlib/atof.c

余生再见 2025-02-07 13:32:49

这是一个支持科学符号的快速函数。这不是最漂亮的,但它起作用。

bool IsFloat(const char* str, unsigned int maxLen = -1)
{
    bool sawD = false;  //decimal
    bool sawE = false;  //exponent
    bool sawES = false; //exponent sign
    int i = 0;

    while (i < maxLen)
    {
        char c = str[i];
        if (c < '0' || c > '9')
        {
            if (!sawD && !sawES && !sawE && c == '.') {
                sawD = true;
            }
            else if (!sawES && !sawE && c == 'e' || c == 'E') {
                sawE = true;
            }
            else if ((i == 0 || !sawES) && c == '+' || c == '-') {
                if (i != 0)
                    sawES = true;
            }
            else if (c == 0) {
                return true;
            }
            else {
                return false;
            }
        }
        i++;
    }
    return true;
}

我(几乎)(几乎)在页面上进行了每个功能。
每个功能都通过循环运行100万次,比较了每个循环21个不同的字符串。字符串列表如下。
我还提供了一个真实表,以显示每个功能产生的内容。空白是真的,x是错误的。

我发现每个函数的性能如此不同,这很有趣。
确实要展示如何使用std ::字符串函数真的可以减慢代码的速度。而且,埃米尔(Emil)的功能还花费了17.7分钟的时间!

用户 时间(MS) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
me 427 x x x x x x x x x x x x x x
x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x
x x x x x x x x x x x x x x x x x x x x x x x x x j_random 108702 x x x x x x x x x x x x x x x x
x x x x x x x x x x x x x x x x x x x x x
x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x
x x x x x x x x x x x x x x x x x x x x x x x x x x x x x X X
Constantin 52918 X X X X X X X X X X X X Bill
108558 X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X
liz 17.7 X X X X X X X X X X
Emil Min X X X X X X

String List

  1. 10.1
  2. -10.1
  3. 0.11
  4. -0.11
  5. 0.0
  6. -0.0
  7. 0
  8. -0
  9. 10 -0 10
  10. -10
  11. 10.11e-
  12. 10.11.11e-10
  13. 10.11e+10
  14. Hello float
  15. Hello1234
  16. Hello11
  17. ​​.11 1234Hello
  18. 1234 Hello
  19. 10.11Hello 10.11Hello
  20. 10.11 Hello
  21. 10.1.1.0.1.1.0.1.1.0.1.1.0

Here is a quick function which supports scientific notation. It's not the prettiest, but it works.

bool IsFloat(const char* str, unsigned int maxLen = -1)
{
    bool sawD = false;  //decimal
    bool sawE = false;  //exponent
    bool sawES = false; //exponent sign
    int i = 0;

    while (i < maxLen)
    {
        char c = str[i];
        if (c < '0' || c > '9')
        {
            if (!sawD && !sawES && !sawE && c == '.') {
                sawD = true;
            }
            else if (!sawES && !sawE && c == 'e' || c == 'E') {
                sawE = true;
            }
            else if ((i == 0 || !sawES) && c == '+' || c == '-') {
                if (i != 0)
                    sawES = true;
            }
            else if (c == 0) {
                return true;
            }
            else {
                return false;
            }
        }
        i++;
    }
    return true;
}

I raced (almost) every function on the page.
Each function was ran through a loop 1 million times, comparing 21 different strings each loop. String list is below.
I also included a truth table to show what each function resulted with. Blank is true, x is false.

I found it pretty interesting how each function performed so differently.
Really goes to show how using the std::string functions can really slow your code down. And also how brutally slow try catch is, Emil's function took a whopping 17.7 minutes to complete!

User Time(ms) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
Me 427 x x x x x x x x
Hayashi 3062 x x x x x x x x
ramakarl 24003 x x x x x x x x x x x x x x x x x x x x x
j_random 108702 x x x x x x x x
nedb 7313 x x x x x x x x
yang 31649 x x x x x x x x x x x
constantin 52918 x x x x x x x x x x x
bill the liz 108558 x x x x x x x x
Robben 112998 x x x x x x x x
Emil 17.7 min x x x

String List

  1. 10.1
  2. -10.1
  3. 0.11
  4. -0.11
  5. 0.0
  6. -0.0
  7. 0
  8. -0
  9. 10
  10. -10
  11. 10.11e-10
  12. -10.11e-10
  13. 10.11e+10
  14. Hello Float
  15. Hello1234
  16. Hello10.11
  17. 1234Hello
  18. 1234 Hello
  19. 10.11Hello
  20. 10.11 Hello
  21. 10.1.0
℡寂寞咖啡 2025-02-07 13:32:49
bool IsFloat (std::string& str)
{
    // erase trailing spaces
    const std::string white_space = " \r\n\t\v\f";
    str.erase(str.find_last_not_of(white_space) + 1);

    bool result = false;

    try 
    {
        size_t pos;
        const float num = std::stof(str, &pos);
        if (pos == str.size())
        {
            result = true;
        }
            
    }
    catch (...) 
    {}

    return result;
}
bool IsFloat (std::string& str)
{
    // erase trailing spaces
    const std::string white_space = " \r\n\t\v\f";
    str.erase(str.find_last_not_of(white_space) + 1);

    bool result = false;

    try 
    {
        size_t pos;
        const float num = std::stof(str, &pos);
        if (pos == str.size())
        {
            result = true;
        }
            
    }
    catch (...) 
    {}

    return result;
}
幸福还没到 2025-02-07 13:32:49

您可以使用 at at af ,然后对 0.0 0.0 0.0 ,但我认为这是一个特别好的解决方案。

You could use atof and then have special handling for 0.0, but I don't think that counts as a particularly good solution.

-残月青衣踏尘吟 2025-02-07 13:32:49

这是一个普遍的问题。查看此问题 string-&gt; int,但方法是相同的)。

注意:要知道字符串是否可以转换,您基本上必须进行转换才能检查诸如Over/Underflow之类的内容。

This is a common question on SO. Look at this question for suggestions (that question discusses string->int, but the approaches are the same).

Note: to know if the string can be converted, you basically have to do the conversion to check for things like over/underflow.

伴我老 2025-02-07 13:32:49

您可以做的是使用Isringstream并根据流操作的结果返回True/False。这样的事情(警告 - 我什至还没有编译代码,这只是指南):

float potential_float_value;
std::istringstream could_be_a_float(MyString)
could_be_a_float >> potential_float_value;

return could_be_a_float.fail() ? false : true;

What you could do is use an istringstream and return true/false based on the result of the stream operation. Something like this (warning - I haven't even compiled the code, it's a guideline only):

float potential_float_value;
std::istringstream could_be_a_float(MyString)
could_be_a_float >> potential_float_value;

return could_be_a_float.fail() ? false : true;
小姐丶请自重 2025-02-07 13:32:49

这取决于您的信任水平,您需要以及输入数据的来源。
如果数据来自用户,则与导入的表数据相比,您必须更加谨慎,在那里您已经知道所有项目都是整数或浮点,而仅这就是您需要区分的东西。

例如,最快的版本之一就是检查“”的存在。和“ EE”。但是,然后,您可能想看看其余的都是数字。从一开始就跳过空格 - 但在中间不在中间,检查一个“”。 因此, “ EE”等。

因此,Q&amp; d快速黑客可能会导致更复杂的正则态度(称其为称为或扫描它)。但是,您怎么知道,结果 - 虽然看起来像浮子 - 确实可以在您的机器中表示(即尝试1.2345678901234567890E1234567890)。当然,您可以在Mantissa/exponent中使用“最新”数字制作正则罚款,但这是机器/OS/编译器或有时(任何特定的)。

因此,最后,可以肯定的是,您可能必须呼吁基础系统的转换并查看您获得的内容(例外,Infinity或NAN)。

it depends on the level of trust, you need and where the input data comes from.
If the data comes from a user, you have to be more careful, as compared to imported table data, where you already know that all items are either integers or floats and only thats what you need to differentiate.

For example, one of the fastest versions, would simply check for the presence of "." and "eE" in it. But then, you may want to look if the rest is being all digits. Skip whitespace at the beginning - but not in the middle, check for a single "." "eE" etc.

Thus, the q&d fast hack will probably lead to a more sophisticated regEx-like (either call it or scan it yourself) approach. But then, how do you know, that the result - although looking like a float - can really be represented in your machine (i.e. try 1.2345678901234567890e1234567890). Of course, you can make a regEx with "up-to-N" digits in the mantissa/exponent, but thats machine/OS/compiler or whatever specific, sometimes.

So, in the end, to be sure, you probably have to call for the underlying system's conversion and see what you get (exception, infinity or NAN).

请叫√我孤独 2025-02-07 13:32:49

我很想忽略领先的空间,因为那是函数的 ath at也:

功能首先放弃了很多
whitespace字符必要
直到第一个非Whitespace
找到角色。然后,开始
从这个角色中,取得了尽可能多的
尽可能有效的字符
按照语法类似
浮点文字,
将它们解释为数值。
最后的弦之后的其余部分
有效角色被忽略,没有
对此行为的影响
功能。

因此,为了匹配这一点:

bool isFloat(string s) 
{ 
    istringstream iss(s); 
    float dummy; 
    iss >> skipws >> dummy; 
    return (iss && iss.eof() );     // Result converted to bool 
} 

I would be tempted to ignore leading whitespaces as that is what the atof function does also:

The function first discards as many
whitespace characters as necessary
until the first non-whitespace
character is found. Then, starting
from this character, takes as many
characters as possible that are valid
following a syntax resembling that of
floating point literals, and
interprets them as a numerical value.
The rest of the string after the last
valid character is ignored and has no
effect on the behavior of this
function.

So to match this we would:

bool isFloat(string s) 
{ 
    istringstream iss(s); 
    float dummy; 
    iss >> skipws >> dummy; 
    return (iss && iss.eof() );     // Result converted to bool 
} 
£噩梦荏苒 2025-02-07 13:32:49

我一直在寻找类似的东西,发现比我看到的任何内容要简单得多(尽管Floats vs. Ints仍然需要字符串打字)

bool is_float(float val){
    if(val != floor(val)){
        return true;
    }
    else
        return false;
}

或:

auto lambda_isFloat = [](float val) {return (val != floor(val)); };

希望这会有所帮助!

zmazz

I was looking for something similar, found a much simpler answer than any I've seen (Although is for floats VS. ints, would still require a typecast from string)

bool is_float(float val){
    if(val != floor(val)){
        return true;
    }
    else
        return false;
}

or:

auto lambda_isFloat = [](float val) {return (val != floor(val)); };

Hope this helps !

ZMazz

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文