【问题标题】:Ways of converting wstring to double with error checking使用错误检查将 wstring 转换为 double 的方法
【发布时间】:2013-09-27 13:04:28
【问题描述】:

我需要将宽字符串转换为双精度数。据推测,该字符串包含一个数字而没有其他内容(可能是一些空格)。如果字符串包含其他任何内容,则应指示错误。所以我不能使用stringstream - 如果字符串包含其他内容,它将提取一个数字而不指示错误。

wcstod 似乎是一个完美的解决方案,但它在 Android(GCC 4.8,NDK r9)上运行错误。我还可以尝试哪些其他选项?

【问题讨论】:

  • 使用std::stod 会在输入错误的情况下抛出异常。
  • "如果字符串包含其他内容,它将提取一个数字而不指示错误。"嗯?如果提取失败,则应设置failbit。 (如果您启用stringstream 的例外,您也会得到一个例外。)
  • @MM.:我相信它是 strtod 的包装,我的输入是宽字符串。
  • @DyP:如果失败,将抛出异常,但此字符串没有错误,我需要在这里出错:“123 asf”。
  • 获取源代码并修复适用于 Android 的 wcstod

标签: c++ string type-conversion double


【解决方案1】:

您可以使用stringstream,然后使用std:ws 来检查流中任何剩余的字符是否只是空格:

double parseNum (const std::wstring& s)
{
    std::wistringstream iss(s);
    double parsed;
    if ( !(iss >> parsed) )
    {
        // couldn't parse a double
        return 0;
    }
    if ( !(iss >> std::ws && iss.eof()) )
    {
        // something after the double that wasn't whitespace
        return 0;
    }
    return parsed;
}

int main()
{
    std::cout << parseNum(L"  123  \n  ") << '\n';
    std::cout << parseNum(L"  123 asd \n  ") << '\n';
}

打印

$ ./a.out 
123
0

(我刚刚在错误情况下返回了0,作为我的示例快速简单的方法。您可能想要throw 或其他东西)。

当然还有其他选择。我只是觉得你对stringstream 的评价不公平。顺便说一句,这是您真正确实想要检查eof()的少数情况之一。

编辑:好的,我添加了ws 和Ls 以使用wchar_ts。

编辑:这是第二个if 在概念上扩展的样子。可能有助于理解为什么它是正确的。

if ( iss >> std::ws )
{ // successfully read some (possibly none) whitespace
    if ( iss.eof() )
    { // and hit the end of the stream, so we know there was no garbage
        return parsed;
    }
    else
    { // something after the double that wasn't whitespace
        return 0;
    }
}
else
{ // something went wrong trying to read whitespace
    return 0;
}

【讨论】:

  • wistringstreamwstring。除此之外,+1。
  • 检查if ( !(iss &gt;&gt; parsed) )是什么意思? operator&gt;&gt; 返回 istream&amp;,而不是布尔值。 istream 可以转换为布尔值吗?
  • @VioletGiraffe 粗略地说,是的,正是为了这个目的。在 C++03 中,std::basic_ios 有一个 operator void*,如果 fail() 返回 true,则返回一个空指针。截至 2011 年,它有一个explicit operator bool,其中behaves like this。基本上,它会读取,然后检查读取是否失败。
  • 请注意,同样的转换也发生在更下方,在iss &gt;&gt; std::ws &amp;&amp; ...
  • 我认为这里的条件是错误的。应该是if (!(iss &gt;&gt; std::ws || iss.eof()))吧?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-02
  • 2016-12-20
  • 1970-01-01
  • 2020-12-01
  • 2021-12-26
  • 2013-01-21
相关资源
最近更新 更多