在 C++ 中将字符串转换为浮点数

Posted

技术标签:

【中文标题】在 C++ 中将字符串转换为浮点数【英文标题】:Convert String to float in c++ 【发布时间】:2011-10-05 19:05:04 【问题描述】:

我想将我从 csv 文件中读取的 std::string 转换为 float。有几种浮点表示,例如:

0,0728239
6.543.584.399
2,67E-02

这些字符串应该都是浮点数。一开始我用atof(),但是转换错了:

2,67E-02 -> 2
6.543.584.399 -> 6.543

然后我使用了boost::lexical_cast<float>(),但是当涉及到包含指数的浮点数时,它会抛出以下异常

`terminate` called after throwing an instance of
`'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::bad_lexical_cast> >'`
`what()`:  bad lexical cast: source type value could not be interpreted as target
Aborted

将所有三种类型的字符串转换为浮点数的最佳方法是什么?

【问题讨论】:

也许您可以向我们展示一个显示各种案例的示例输入? @iam_peter:预期的结果是什么? 6.543.584.399不能与0.0728239同时有效 语言环境是你告诉 C++ “我使用 . 来分隔数千个组,并使用 , 来分隔小数部分的整个部分。”默认情况下,C++ 将使用C locale,它使用. 将整个部分与小数部分分开,并且不使用任何东西来分隔数千个组。有一种使用语言环境(www2.research.att.com/~bs/3rd_loc0.html)的“C++ 方式”,但没有人使用它,一些编译器也没有实现它。不过,“C 方式”非常简单。 @sehe:欧洲国家不正确。他们交换了我们的逗号和小数点。 @iam_peter:哎呀。当然 :) 这更有意义。 @MooingDuck:不小心点赞了你的评论。关键是样本本身不一致。没有支持 that 的欧洲语言环境(OT:我自己来自这样一个欧洲国家 :)) 【参考方案1】:

scanf 设置正确的语言环境。严重地。在这种情况下,您可以省去“c++ 方式”的麻烦。

【讨论】:

atof() 几乎不是“C++ 方式”,一旦你设置了当前的语言环境,它就可以正常工作。 我没有提到 atof(),但让我补充一点,我认为 scanf 是要走的路,因为 atof 不会告诉你它是否无法解析字符串。 OP 试图使用atof。您批评他“以 C++ 方式做事”。您确实提出了一个很好的观点,即atof 没有告诉它是否无法解析字符串。【参考方案2】:

http://www.cplusplus.com/reference/clibrary/clocale/

请注意,语言环境配置会影响许多人的行为 标准 C 库中的函数:在 string.h 中, 函数 strcoll 和 strxfrm 受字符转换的影响 规则。在 ctype.h 中,除了 isdigit 和 isxdigit 受所选扩展字符集的影响。在 stdio.h,格式化输入/输出操作受到影响 通过字符转换规则和小数点字符集 数字格式设置。在 time.h 中,函数 strftime 受时间格式设置的影响。在这个标题中, 它影响其函数 setlocale 和返回的值 localeconv.

http://www.cplusplus.com/reference/clibrary/clocale/setlocale/

setlocale ( LC_NUMERIC, "" ); // "" is the Environment's default locale

然后就可以正确使用atof、scanf等了。然而,这就是 C 的做事方式。 C++方式是:

float stof(const std::string& input) 
    std::stringstream ss;
    float result;
    static std::locale uselocale("") //again, "" is Environment's default locale
    ss.imbue(uselocale);
    ss << input;
    ss >> result;
    return result;

所有编译器都必须接受以下语言环境:“”、“C” MSVC 接受以下语言环境:http://msdn.microsoft.com/en-us/library/hzz3tw78.aspx (等等,MSVC setlocale 真的不接受“en_US”吗?) GCC 接受这些语言环境:http://gcc.gnu.org/onlinedocs/libstdc++/manual/localization.html#locale.impl.c

【讨论】:

【参考方案3】:

应该这样做:

#include <sstream>
#include <iostream>
#include <algorithm>

bool isdot(const char &c)

    return '.'==c;


float to(std::string s)

    s.erase(std::remove_if(s.begin(), s.end(), &isdot ),s.end());
    replace(s.begin(), s.end(), ',', '.');


    std::stringstream ss(s);
    float v = 0;
    ss >> v;
    return v;


int main()

    const std::string a1("0,0728239");
    const std::string a2("6.543.584.399");
    const std::string a3("2,67E-02");

    std::cout << to(a1)<<std::endl;
    std::cout << to(a2)<<std::endl;
    std::cout << to(a3)<<std::endl;

看live on coliru

【讨论】:

以上是关于在 C++ 中将字符串转换为浮点数的主要内容,如果未能解决你的问题,请参考以下文章

如何在python中将23位浮点数从字符串转换为浮点数并返回?

无法在python中将字符串转换为浮点数

ValueError:无法在熊猫中将字符串转换为浮点数

如何在 JavaScript 中将字符串转换为浮点数?

如何在 C++ 中将数字转换为字符串,反之亦然

在 Objective-C 中将货币字符串转换为浮点数