6

我有一个可以是数字的字符串(甚至是浮点型或双精度型,不仅是整数),它也可以是非数字的单词。

我想检查这个字符串是否可以转换成双精度,如果可以,那么我想做转换。如果是非数字字符串,我想要不同的行为。

我试过这个:

double tmp;
string str;
stringstream ss;

ss << str;
ss >> tmp;

if (ss.fail())
{
    // non-numeric string
}
else
{
    // string to double conversion is successful
}

这段代码的问题ss.fail()是总是true,即使tmp包含正确的值。

有一个函数atof()可以将字符串转换为双精度,但这不适合我,因为0.0如果输入字符串不是数字,它会返回值。这样我就无法区分非数字和零输入值。

4

6 回答 6

7

std::stod 呢?当它无法执行转换时,它会抛出 std::out_of_range 。

try
{
    double value = std::stod(input_string);
    std::cout << "Converted string to a value of " << value << std::endl;
}
catch(std::exception& e)
{
    std::cout << "Could not convert string to double" << std::endl;
}

我没有尝试编译它,但你应该明白了。

于 2013-10-13T19:23:01.087 回答
7

如果您的输入字符串具有来自 std::string 的类型(它适用于 Windows 和 unix 系统),则可以使用此函数:

#include <stdlib.h>
#include <string>
/**
* @brief checkIsDouble - check inputString is double and if true return double result
* @param inputString - string for checking
* @param result - return double value
* @return true if string is double, false if not
*/
bool checkIsDouble(string inputString, double &result) {
    char* end;
    result = strtod(inputString.c_str(), &end);
    if (end == inputString.c_str() || *end != '\0') return false;
    return true;
}
于 2016-10-02T02:14:13.940 回答
0

检查空白和流结束

if ((ss >> tmp) && (ss >> std::ws).eof() )
{
   // a double

}

提取一个double值,然后提取任何空格,如果在此期间遇到 eof,则意味着您只有一个有效double

于 2013-10-13T19:14:37.233 回答
0

小心使用std::ws,因为如果它已经EOF,它会触发failbit。因此,以下建议不适用于“9.000”之类的情况。由于 cl 错误,这在 Visual Studio 2015 中有效。但是在 VS2019 中,该错误已修复并且失败了。

if ((ss >> tmp) && (ss >> std::ws).eof() )
{
   // a double

}

你可以考虑下面的代码

if ((ss >> tmp) && (  ss.eof() ||  (ss >> std::ws).eof()) )
{
   // a double

}

有关 VS 错误的详细信息: https ://developercommunity.visualstudio.com/t/regression-stdws-incorrectly-sets-failbit-when-the/382896

于 2021-09-11T03:08:48.977 回答
0

一个较少cpp-ish的解决方案怎么样:

double number;
string str;

if (sscanf(str.c_str(), "%lf", &number) != 1)
{
    // non-numeric string
}
else
{
    // string to double conversion is successful
}
于 2020-11-19T19:19:45.857 回答
0

什么是有效号码?是 atof() 将解析的任何内容,还是您对空格有规则?你允许科学记数法,前导 - 前导 + 吗?数字后面可以有其他数据吗?必须有小数点还是接受整数?你接受一个小数点前导还是必须以 0 开头?你接受 00.1 吗?你接受 0.1FRED 但拒绝 0.1.2FRED 吗?

函数 strtod() 就是为这个问题而设计的。atof() 现在基本上已经过时了,因为它不够健壮,无法处理格式错误的输入。然而 strtod() 不够灵活,无法接受格式正确的输入的特定规则。如果规则很简单,编写自己的临时匹配器并不难——跳过空格、匹配数字、匹配小数点、匹配数字、跳过空格。如果您需要完全的灵活性,最终您必须求助于正则表达式,这是一种大锤的答案。

于 2016-10-02T03:23:05.110 回答