在 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++ 中将字符串转换为浮点数的主要内容,如果未能解决你的问题,请参考以下文章