我正在尝试将std::string
转换为float/double
。
我试过了:
std::string num = "0.6";
double temp = (double)atof(num.c_str());
但它总是返回零。还有其他方法吗?
答案 0 :(得分:113)
std::string num = "0.6";
double temp = ::atof(num.c_str());
对我来说,将字符串转换为double是一种有效的C ++语法。
你可以使用stringstream或boost :: lexical_cast来实现它,但这些会带来性能损失。
Ahaha你有一个Qt项目......
QString winOpacity("0.6");
double temp = winOpacity.toDouble();
额外注意事项:
如果输入数据为const char*
,则QByteArray::toDouble
会更快。
答案 1 :(得分:89)
标准库(C ++ 11)通过std::stod
提供所需的功能:
std::string s = "0.6"
std::wstring ws = "0.7"
double d = std::stod(s);
double dw = std::stod(ws);
我想标准库也在内部转换,但这种方式使代码更清晰。通常,对于大多数其他基本类型,请参阅<string>
。 C字符串也有一些新功能。见<stdlib.h>
答案 2 :(得分:27)
词汇演员非常好。
#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;
}
答案 3 :(得分:14)
您可以使用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");
答案 4 :(得分:9)
是的,有一个词汇演员。使用字符串流和&lt;&lt;运营商,或使用Boost,他们已经实现了它。
您自己的版本可能如下所示:
template<typename to, typename from>to lexical_cast(from const &x) {
std::stringstream os;
to ret;
os << x;
os >> ret;
return ret;
}
答案 5 :(得分:7)
你可以使用boost lexical cast:
#include <boost/lexical_cast.hpp>
string v("0.6");
double dd = boost::lexical_cast<double>(v);
cout << dd << endl;
注意:boost :: lexical_cast抛出异常,所以你应该准备好在传递无效值时处理它,尝试传递字符串(“xxx”)
答案 6 :(得分:4)
如果你不想拖动所有提升,请从strtod(3)
开始使用<cstdlib>
- 它已经返回了一个双倍。
#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++ -o s s.cc
$ ./s
0.6 0.6
$
为什么atof()不起作用...你在使用什么平台/编译器?
答案 7 :(得分:3)
我在Linux中遇到了同样的问题
double s2f(string str)
{
istringstream buffer(str);
double temp;
buffer >> temp;
return temp;
}
它有效。
答案 8 :(得分:1)
这个答案在你的评论中备份。我怀疑你只是没有正确地显示结果。
我曾经发生过同样的事情。我花了一整天时间试图找出为什么我在64位int中得到一个坏值,却发现printf忽略了第二个字节。您不能只将64位值传递给printf,就像它的int。
一样答案 9 :(得分:1)
double myAtof ( string &num){
double tmp;
sscanf ( num.c_str(), "%lf" , &tmp);
return tmp;
}
答案 10 :(得分:1)
C ++ 11方法是使用std :: stod和std :: to_string。两者都可以在Visual Studio 11中使用。
答案 11 :(得分:1)
至于为什么atof()
在原始问题中不起作用:它被强制转换的事实让我怀疑。代码不应该在没有#include <stdlib.h>
的情况下编译,但是如果添加了强制转换以解决编译警告,那么atof()
未正确声明。如果编译器假定atof()
返回一个int,则转换它将解决转换警告,但它 not 会导致返回值被识别为double。
#include <stdlib.h>
#include <string>
...
std::string num = "0.6";
double temp = atof(num.c_str());
应该在没有警告的情况下工作。
答案 12 :(得分:1)
在 C++17 中,您可以使用 std::from_chars
,它是 std::stof
和 std::stod
的更轻量更快的替代品。它不涉及任何内存分配或查看语言环境,并且不抛出。
std::from_chars
函数返回一个 from_chars_result
类型的值,它基本上是一个具有两个字段的结构:
struct from_chars_result {
const char* ptr;
std::errc ec;
};
通过检查 ec
我们可以判断转换是否成功:
#include <iostream>
#include <charconv>
int main()
{
const std::string str { "12345678901234.123456" };
double value = 0.0;
auto [p, ec] = std::from_chars(str.data(), str.data() + str.size(), value);
if (ec != std::errc()) {
std::cout << "Couldn't convert value";
}
return 0;
}
注意:您需要一个相当最新的编译器(例如 gcc11),std::from_chars
才能处理浮点类型。
答案 13 :(得分:0)
您可以将字符串(暂时)保留为char[]
并使用sprintf()
,而不是将Boost拖入等式中。
但是当然如果你还在使用Boost,那真的不是一个问题。
答案 14 :(得分:0)
你不希望Boost lexical_cast用于字符串&lt; - &gt;无论如何浮点。这个用例子集是唯一一个比旧功能更糟糕的设置 - 他们基本上将所有故障集中在那里,因为他们自己的性能结果显示比使用sscanf和printf进行此类转换的性能低20-25倍。
谷歌自己。 boost :: lexical_cast可以处理类似50次转换的事情,如果你排除涉及浮点#s的那些转换它与显而易见的替代品一样好或更好(具有为所有这些操作使用单个API的额外优势)。但是带上花车,就像泰坦尼克号在性能方面遇到冰山一样。
旧的专用str-&gt;双重函数都可以在30毫秒(或更好)的时间内完成10000次分析。 lexical_cast需要650毫秒才能完成同样的工作。
答案 15 :(得分:0)
我的问题:
我的解决方案(使用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 ......我花了很长时间才得到这个解决方案。我仍然觉得我对字符串本地化和东西不够了解......