std :: string来浮动或双精度
我试图将std::string
转换为float/double
。 我试过了:
std::string num = "0.6"; double temp = (double)atof(num.c_str());
但它总是返回零。 任何其他方式?
std::string num = "0.6"; double temp = ::atof(num.c_str());
对我来说,将string转换为double是一种有效的C ++语法。
你可以用stringstream或boost :: lexical_cast来完成,但是这些都会带来性能上的损失。
啊哈哈,你有一个Qt项目…
QString winOpacity("0.6"); double temp = winOpacity.toDouble();
额外说明:
如果input数据是一个const char*
, QByteArray::toDouble
将会更快。
标准库(C ++ 11)提供了std::stod
所需的function:
std::string s = "0.6" std::wstring ws = "0.7" double d = std::stod(s); double dw = std::stod(ws);
我猜标准库也可以在内部进行转换,但这样可以使代码更清晰。 通常对于大多数其他基本types,请参见<string>
。 Cstring也有一些新的function。 参见<stdlib.h>
词法演员是非常好的。
#include <boost/lexical_cast.hpp> #include <iostream> #include <string> using std::endl; using std::cout; using std::string; using boost::lexical_cast; int main() { string str = "0.6"; double dub = lexical_cast<double>(str); cout << dub << endl; }
你可以使用std :: stringstream:
#include <sstream> #include <string> template<typename T> T StringToNumber(const std::string& numberAsString) { T valor; std::stringstream stream(numberAsString); stream >> valor; if (stream.fail()) { std::runtime_error e(numberAsString); throw e; } return valor; }
用法:
double number= StringToNumber<double>("0.6");
是的,有一个词汇表。 使用一个stringstream和<<运算符,或者使用Boost,他们已经实现了它。
您自己的版本可能如下所示:
template<typename to, typename from>to lexical_cast(from const &x) { std::stringstream os; to ret; os << x; os >> ret; return ret; }
你可以使用boost词法转换:
#include <boost/lexical_cast.hpp> string v("0.6"); double dd = boost::lexical_cast<double>(v); cout << dd << endl;
注意:boost :: lexical_cast抛出exception,所以当你传递无效值时,你应该准备好处理它,尝试传递string(“xxx”)
我在Linux中遇到同样的问题
double s2f(string str) { istringstream buffer(str); double temp; buffer >> temp; return temp; }
有用。
如果你不想拖动所有的boost,使用<cstdlib>
strtod(3)
– 它已经返回一个double。
#include <iostream> #include <string> #include <cstring> #include <cstdlib> using namespace std; int main() { std::string num = "0.6"; double temp = ::strtod(num.c_str(), 0); cout << num << " " << temp << endl; return 0; }
输出:
$ g++ -os s.cc $ ./s 0.6 0.6 $
为什么atof()不工作…你在什么平台/编译器?
这个答案是在你的评论中备份的。 我有深刻的怀疑,你只是没有正确显示结果。
我曾经遇到过同样的事情。 我花了整整一天的时间,试图弄清楚为什么我把一个坏的值变成了一个64位的int,只是发现printf忽略了第二个字节。 你不能只是像一个int一样传递一个64位的值到printf中。
double myAtof ( string &num){ double tmp; sscanf ( num.c_str(), "%lf" , &tmp); return tmp; }
C ++ 11的方法是使用std :: stod和std :: to_string。 两者都在Visual Studio 11中工作。
至于为什么atof()
在原来的问题中没有起作用:事实上它被加倍使我怀疑。 如果没有#include <stdlib.h>
不能编译代码,但是如果添加了atof()
来解决编译警告,那么atof()
就没有正确的声明。 如果编译器假定atof()
返回一个int值,那么强制转换将解决转换警告,但不会导致返回值被识别为double。
#include <stdlib.h> #include <string> ... std::string num = "0.6"; double temp = atof(num.c_str());
应该没有警告地工作。
您可以将string(暂时)保留为char[]
并使用sprintf()
,而不是将Boost拖入等式中。
但是,当然,如果你使用Boost,那也不算什么问题。
无论如何,您不希望为string< – >浮点提升lexical_cast。 使用案例的子集是唯一的提升始终比旧的function更糟 – 他们基本上集中所有的失败,因为他们自己的性能结果显示比使用sscanf和printf这样的转换20-25X SLOWER性能。
谷歌它自己。 boost :: lexical_cast可以处理50个转换,如果你排除涉及浮点#s的那些,它就像明显的替代品一样好或者更好(具有为所有这些操作具有单个API的附加优点)。 但是引进花车,就像泰坦尼克号在性能上打冰山一样。
旧的,专用的str-> double函数可以在30 ms(或更好)的情况下进行10000次parsing。 lexical_cast需要650毫秒来做同样的工作。
我的问题:
- 区域独立的string加倍(小数点分隔符总是'。')
- 错误检测如果string转换失败
我的解决scheme(使用Windows函数_wcstod_l):
// string to convert. Note: decimal seperator is ',' here std::wstring str = L"1,101"; // Use this for error detection wchar_t* stopString; // Create a locale for "C". Thus a '.' is expected as decimal separator double dbl = _wcstod_l(str.c_str(), &stopString, _create_locale(LC_ALL, "C")); if (wcslen(stopString) != 0) { // ... error handling ... we'll run into this because of the separator }
HTH …花了我很长时间才得到这个解决scheme。 而且我还是觉得我对string本地化和东西不够了解…