Programing

std :: string to float 또는 double

lottogame 2020. 9. 10. 08:21
반응형

std :: string to float 또는 double


나는 변환하려고 해요 std::stringfloat/double. 나는 시도했다 :

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

그러나 항상 0을 반환합니다. 다른 방법은 없나요?


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빠른 것입니다.


표준 라이브러리 (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>


어휘 캐스트는 매우 좋습니다.

#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");

Yes, with a lexical cast. Use a stringstream and the << operator, or use Boost, they've already implemented it.

Your own version could look like:

template<typename to, typename from>to lexical_cast(from const &x) {
  std::stringstream os;
  to ret;

  os << x;
  os >> ret;

  return ret;  
}

You can use boost lexical cast:

#include <boost/lexical_cast.hpp>

string v("0.6");
double dd = boost::lexical_cast<double>(v);
cout << dd << endl;

Note: boost::lexical_cast throws exception so you should be prepared to deal with it when you pass invalid value, try passing string("xxx")


If you don't want to drag in all of boost, go with strtod(3) from <cstdlib> - it already returns a 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;
}

Outputs:

$ g++ -o s s.cc
$ ./s
0.6 0.6
$

Why atof() doesn't work ... what platform/compiler are you on?


I had the same problem in Linux

double s2f(string str)
{
 istringstream buffer(str);
 double temp;
 buffer >> temp;
 return temp;
}

it works.


This answer is backing up litb in your comments. I have profound suspicions you are just not displaying the result properly.

I had the exact same thing happen to me once. I spent a whole day trying to figure out why I was getting a bad value into a 64-bit int, only to discover that printf was ignoring the second byte. You can't just pass a 64-bit value into printf like its an int.


   double myAtof ( string &num){
      double tmp;
      sscanf ( num.c_str(), "%lf" , &tmp);
      return tmp;
   }

The C++ 11 way is to use std::stod and std::to_string. Both work in Visual Studio 11.


As to why atof() isn't working in the original question: the fact that it's cast to double makes me suspicious. The code shouldn't compile without #include <stdlib.h>, but if the cast was added to solve a compile warning, then atof() is not correctly declared. If the compiler assumes atof() returns an int, casting it will solve the conversion warning, but it will not cause the return value to be recognized as a double.

#include <stdlib.h>
#include <string>

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

should work without warnings.


Rather than dragging Boost into the equation, you could keep your string (temporarily) as a char[] and use sprintf().

But of course if you're using Boost anyway, it's really not too much of an issue.


You don't want Boost lexical_cast for string <-> floating point anyway. That subset of use cases is the only set for which boost consistently is worse than the older functions- and they basically concentrated all their failure there, because their own performance results show a 20-25X SLOWER performance than using sscanf and printf for such conversions.

Google it yourself. boost::lexical_cast can handle something like 50 conversions and if you exclude the ones involving floating point #s its as good or better as the obvious alternatives (with the added advantage of being having a single API for all those operations). But bring in floats and its like the Titanic hitting an iceberg in terms of performance.

The old, dedicated str->double functions can all do 10000 parses in something like 30 ms (or better). lexical_cast takes something like 650 ms to do the same job.


My Problem:

  1. Locale independent string to double (decimal separator always '.')
  2. Error detection if string conversion fails

My solution (uses the Windows function _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 ... took me pretty long to get to this solution. And I still have the feeling that I don't know enough about string localization and stuff...

참고URL : https://stackoverflow.com/questions/1012571/stdstring-to-float-or-double

반응형