std :: string为float或double

时间:2009-06-18 13:15:59

标签: c++

我正在尝试将std::string转换为float/double。 我试过了:

std::string num = "0.6";
double temp = (double)atof(num.c_str());

但它总是返回零。还有其他方法吗?

16 个答案:

答案 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::stofstd::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)

我的问题:

  1. 区域设置独立字符串为double(小数点分隔符始终为'。')
  2. 如果字符串转换失败则检测错误
  3. 我的解决方案(使用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 ......我花了很长时间才得到这个解决方案。我仍然觉得我对字符串本地化和东西不够了解......