喜欢 atoi 但要漂浮
Posted
技术标签:
【中文标题】喜欢 atoi 但要漂浮【英文标题】:like atoi but to float 【发布时间】:2011-02-16 13:26:46 【问题描述】:有没有类似 atoi 的函数将字符串转换为浮点数而不是整数?
【问题讨论】:
这可能是一个 C 问题而不是 C++。 atoi 是 C 标准库的一部分。 @RED SOFT ADAIR:atoi
完全可以在 C++ 中使用。
这和我说的不冲突。
@RED:好吧,OP 将其标记为 C++,我只是假设他们最清楚自己需要什么。
【参考方案1】:
atof()
(或 std::atof()
会说话的 C++ - 谢谢 jons34yp)
【讨论】:
@Glen: 和atoi
转换为long
,那又怎样?
@Glen:你真的想要那 3 页解释为什么没有 atof_float() 吗? atof() 是解决与 atoi 等价问题的问题的正确答案。问题不是:“还有其他函数可以从字符串转换为数字类型吗?”。
boost::lexical_cast
和 strtof
都是比atof
更好的解决方案,因为atof
没有错误检测。
@Glen, @RED:虽然问题确实以同样的方式询问“浮点”(不是float
),但它提到了“整数”(不是int
),因此答案使用double
应该没问题,这个答案仍然很糟糕,因为所有 atox()
函数都具有错误字符串返回有效值的内置缺陷。对于一个糟糕透顶的 API 函数。
If no conversion can be performed, 0.0 is returned.
为什么有人会使用一个错误返回 0.0 的愚蠢函数? 0.0 可能是一个有效值,与垃圾输入没有区别。我一点也不喜欢这个。【参考方案2】:
boost::lexical_cast<float>(str);
此模板函数包含在流行的 Boost 库集合中,如果您对 C++ 很认真,您会想要了解这些库。
【讨论】:
这需要下载和安装 boost (apx. 500 MB)。你应该在你的回答中注意到这一点。否则 C++ 新手会感到困惑。 在我的系统上,这需要一个简单的sudo apt-get libboost-dev
并且可能需要等待我缓慢的互联网链接。
@sbi,我基本同意,但是一些聪明、非常有才华的开发人员可能由于很多原因(政治是一个很大的原因)无法获得提升。这不是一个很好的情况,但是将它们写成“不值得他们花钱”有点苛刻。
哦,伙计,我多年来一直在使用 boost。一次又一次让我印象深刻的是,这样一个简单的问题会引发这样的“宗教”冲突。
@Glen:是的,你是对的,讨厌的公司政策不断出现作为不使用 boost 的理由。 @RED:我很抱歉,这确实有点苛刻。我已删除我的评论。【参考方案3】:
将字符串转换为任何类型(默认可构造且可流式传输):
template< typename T >
T convert_from_string(const std::string& str)
std::istringstream iss(str);
T result;
if( !(iss >> result) ) throw "Dude, you need error handling!";
return result;
【讨论】:
感谢唯一基于 C++ 的解决方案!所有其他答案均指 C 语言,但问题标记为 C++。 @Mass:除了larsmans's answer,更优雅。 @Kenji: Boost 不是不必要的,错误处理不正确,并且它不能有效地工作(或者在空格的情况下不能正常工作)。我确信lexical_cast<>()
得到了这(以及更多)都涵盖了。
@Kenji:首先,扔字符串字面量肯定会下地狱——在回答新手问题时这样做很可能会将无辜者送入地狱。此外,此代码不会检查字符串中是否有未使用的非空白字符,这可能是一个错误。虽然问题是关于浮点数的,但答案几乎可以转换任何可流式传输的内容,因此它应该适用于几乎所有内容。在设计和实施boost::lexical_cast
时已经考虑了所有这些以及更多。如果它是劣质的,为什么要自己滚动?
“在我工作的地方,我们有自己的术语来形容此处未发明的综合症。”【参考方案4】:
strtof
来自手册页
strtod()、strtof() 和 strtold() 函数将 nptr 指向的字符串的初始部分分别转换为 double、float 和 long double 表示形式。
字符串(的初始部分)的预期形式是可选的前导空格,如 isspace(3) 所识别,可选的加号 (''+'') 或减号 (''-''),然后(i) 十进制数,或 (ii) 十六进制数,或 (iii) 无穷大,或 (iv) NAN(非数字)。
/手册页>
atof 将字符串转换为双精度(不是顾名思义的浮点数。)
【讨论】:
【参考方案5】:作为已经提到的std::strtof()
和boost::lexical_cast<float>()
的替代品,引入了新的C++ 标准
float stof(const string& str, size_t *idx = 0);
double stod(const string& str, size_t *idx = 0);
long double stold(const string& str, size_t *idx = 0);
用于错误检查字符串到浮点的转换。 GCC 和 MSVC 都支持它们(记得#include <string>
)
【讨论】:
那些真的在<string>
(而不是在<cstring>
)吗?
@sbi 他们在<string>
per 21.3[string.classes]【参考方案6】:
使用来自stdlib.h
的atof
:
double atof ( const char * str );
【讨论】:
【参考方案7】:首选strtof()
。 atof()
不检测错误。
【讨论】:
其实更喜欢字符串流,除非你知道你有性能问题。不过,+1
来自我,因为 atox()
系列函数在其界面中内置了一个致命缺陷是正确且重要的。
您能否提供有关使用 atof() 问题的链接?我使用它已有 20 年了 - 我不记得有任何问题。
man atof
:atof()
函数将 nptr 指向的字符串的初始部分转换为 double。行为与strtod(nptr, (char **) NULL);
相同除了atof()
不检测错误。
哦,windows 程序员,这就解释了,哈哈。 atof()
未检测到 解析 错误。试试std::cout << atof("2abc123") << '\n';
。
如果字符串在解析和转换之间损坏,atof()
不会注意到。【参考方案8】:
这也可以(但 C 类代码):
#include <iostream>
using namespace std;
int main()
float myFloatNumber = 0;
string inputString = "23.2445";
sscanf(inputString.c_str(), "%f", &myFloatNumber);
cout<< myFloatNumber * 100;
在这里查看: http://codepad.org/qlHe5b2k
【讨论】:
【参考方案9】:#include <stdlib.h>
double atof(const char*);
还有strtod
。
【讨论】:
atof 和 strtod 都转换为 double 而不是 float。【参考方案10】:试试 boost::spirit:快速、类型安全且非常高效:
std::string::iterator begin = input.begin();
std::string::iterator end = input.end();
using boost::spirit::float_;
float val;
boost::spirit::qi::parse(begin,end,float_,val);
【讨论】:
【参考方案11】:作为上述所有方法的替代方案,您可以使用字符串流。 http://cplusplus.com/reference/iostream/stringstream/
【讨论】:
以上是关于喜欢 atoi 但要漂浮的主要内容,如果未能解决你的问题,请参考以下文章