std :: string to float 또는 double


98

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

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

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


3
이미 10 년 전에 알아 낸 것을 과도하게 설계하려는 충동을 저항하십시오.
haavee 2009-06-18

1
올바르게 출력 했습니까? 그것은 제로 양보 안
litb - 요하네스 SCHAUB

1
또한 atof를 캐스팅 할 필요가 없으며 이미 double을 반환합니다.
AlbertoPL

확실해. 디버거에 0이 표시되고 결과는 0입니다. 플랫폼 : Linux.
Max Frai

13
올바른 로케일이 설치되어 있습니까? "0,6"또는 setlocale (LC_NUMERIC, "C");
Johannes Schaub-litb

답변:


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


7
boost :: lexical_cast가 스트리밍 중입니다.
TimW

1
일반적으로 성능 저하가 있다고 말할 수는 없습니다. 바로 전에 cin >> num;이있을 때 어떤 일이 발생하는지 생각해보십시오. 사용자는 지금까지 느린 lexical_cast 밀리 초를주의하는 것이 매우 빠르게 (RLY 존이 같은 스키트)를 입력해야합니다 :) 그건 내가 lexical_cast 그냥 :) 너무 많은 성능을 짜증 태스크가 생각했다
요하네스 SCHAUB - litb

3
이 솔루션에서 :: atof () 앞의 기능은 무엇입니까? 거기에 무엇이 필요합니까?
sivabudh

4
@ShaChris 글로벌 네임 스페이스에서 atof 함수를 사용하고 싶기 때문입니다.
TimW

1
현재 로케일에 따라 다름
nmr

104

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


4
이 솔루션을 좋아하지만 C ++ 11에서만 나온 것 같습니다. 그래서 내 SDK에서 사용할 수 없습니다.
pamplemousse_mk2 2013 년

그것은이다 중대한 는 C ++ 표준위원회는이 추가 된 것을 알 수 있습니다. ostringstream그 자체로는 .. 혼자 사용하게 밖으로 입력 단순히 너무 긴
bobobobo

4
float의 경우 ( "c ++ string to float"를 입력하여 Google에서 찾은 질문에서 질문했듯이) std :: stof를 사용해야합니다.
에티엔

1
이 예외를 던질 수 있다는 것을 그냥 참고 : 표준 : invalid_argument을 (변환이 실패 할 경우는) 표준 : : out_of_range을합니다 (범위를 벗어난 경우)
제이슨 Doucette

3
구매자는 현재 로케일에 따라주의해야합니다.
nmr

29

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

#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;
}

감사합니다. 작동합니다.하지만 제게 질문입니다. 내 코드가 작동하지 않는 이유입니다.
Max Frai

2
@Johannes Schaub : ADL을 기반으로 할 때, 사용 정의와 그가 실제로 사용하고있는 내용은 아마도 방대한 수의 표준 요소를 범위로 가져올 것입니다. 또한 lexical_cast는 엄청나게 느리므로 나에게서 +1이 없습니다.

boost :: lexical_cast의 좋은 기능은 오류 처리입니다. 변환이 실패하면 예외가 발생합니다.try { ... boost::lexical_cast ... } catch (std::exception const& err) { //handle excpetion }
Semjon Mössinger

더 정확하게 말하면를 사용 catch ( boost::bad_lexical_cast const& err )하여 예외를 포착하십시오.
Semjon Mössinger

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

음, 그래서 당신은 boost :: lexical_cast가 끔찍한 인터페이스를 가지고 있다고 생각하지 않습니까? stefanB의 대답을보세요! Boost도 마찬가지입니다.
kirsche40

@ kirsche40 이미 부스트와 의존성이없는 사람들을위한 좋은 대안처럼 보인다 (숫자 만에 표준 : : 문자열을 변환하는 부스트와 약간의 과잉이다 연결을!)
장 - 필립 Jodoin

@ JEan-Phillippe Jodiun 누군가가 Boost를 추천 한 지금 삭제 된 댓글에 답했습니다. 나는 Boost가 대부분의 시간 과잉이라는 것을 알고 있습니다. 그건 그렇고, 얼마 동안 Boost의 사용은 "최신"컴파일러로 제한됩니다. 이전 프로젝트는 Boost를 사용할 수 없습니다. 예를 들어 ASIO는 std :: addressof와 같은 C ++ 11 기능에 크게 의존하므로 C ++ 98 / C ++ 03 컴파일러에는 전혀 쓸모가 없습니다. IMHO, 프로젝트가 시작되었을 때 이전 컴파일러 버전에 대한 새로운 "표준화 된"기능을 제공하는 것이 Boost의 의도였습니다 ... :-(
kirsche40

10

예, 어휘 캐스트로. stringstream과 << 연산자를 사용하거나 Boost를 사용하면 이미 구현되어 있습니다.

자신의 버전은 다음과 같습니다.

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

  os << x;
  os >> ret;

  return ret;  
}

7

부스트 어휘 캐스트를 사용할 수 있습니다.

#include <boost/lexical_cast.hpp>

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

참고 : boost :: lexical_cast에서 예외가 발생하므로 잘못된 값을 전달할 때 처리 할 준비가되어 있어야합니다. string ( "xxx")을 전달해보십시오.


5

모든 부스트를 드래그하지 않으려면 strtod(3)from으로 이동 <cstdlib>하십시오. 이미 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++ -o s s.cc
$ ./s
0.6 0.6
$

atof ()가 작동하지 않는 이유 ... 어떤 플랫폼 / 컴파일러를 사용하고 있습니까?


stringstream을 사용하면 부스트가 필요하지 않습니다
jalf 2009-06-18

귀하의 메서드도 0을 반환합니다. 리눅스.
Max Frai

3

나는 리눅스에서 같은 문제가 있었다

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

효과가있다.


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

1
잘못된 대답, num에 저장된 값이 실제로 유효한 부동 소수점 숫자인지 어떻게 알 수 있습니까? sscanf의 반환 유형을 확인하지 않으면 MS 코딩 스타일처럼 보입니다.

1

이 답변은 귀하의 의견에 litb를 백업하고 있습니다. 나는 당신이 결과를 제대로 표시하지 않고 있다는 심오한 의혹을 가지고 있습니다.

나에게 똑같은 일이 한 번 일어났습니다. 나는 왜 내가 64 비트 int에 나쁜 값을 가져 오는지 알아 내려고 하루 종일 보냈지 만, printf가 두 번째 바이트를 무시하고 있다는 것을 발견했다. int처럼 64 비트 값을 printf에 전달할 수는 없습니다.


결과를보기 위해 printf를 사용하지 않고 있습니다. 그리고이 값을 사용하여 창 불투명도를 설정하고 창은 완전히 투명하므로 값은 0입니다.
Max Frai

1

C ++ 11 방식은 std :: stod 및 std :: to_string을 사용하는 것입니다. 둘 다 Visual Studio 11에서 작동합니다.


1

atof()원래 질문에서 작동하지 않는 이유 는 이중으로 캐스팅되었다는 사실이 나를 의심하게 만듭니다. 코드는없이 컴파일해서는 #include <stdlib.h>안되지만 컴파일 경고를 해결하기 위해 캐스트가 추가 된 경우 atof()올바르게 선언되지 않습니다. 컴파일러 atof()가 int를 반환 한다고 가정 하면 캐스팅하면 변환 경고가 해결되지만 반환 값이 double로 인식 되지않습니다 .

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

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

경고없이 작동해야합니다.


0

Boost를 방정식으로 드래그하는 대신 문자열을 (일시적으로) a로 유지 char[]하고 sprintf().

그러나 물론 Boost를 사용하는 경우에는 실제로 큰 문제가 아닙니다.


0

어쨌든 string <-> 부동 소수점에 대해 Boost lexical_cast를 원하지 않습니다. 사용 사례의 하위 집합은 부스트가 이전 기능보다 지속적으로 더 나쁜 유일한 세트이며 기본적으로 자체 성능 결과가 이러한 변환에 sscanf 및 printf를 사용하는 것보다 20-25 배 느린 성능을 보여주기 때문에 기본적으로 모든 오류를 여기에 집중 시켰습니다.

직접 구글링하세요. boost :: lexical_cast는 50 개의 변환과 같은 것을 처리 할 수 ​​있으며 부동 소수점 #s와 관련된 변환을 제외하면 명백한 대안만큼 좋거나 더 좋습니다 (모든 작업에 대해 단일 API를 갖는 추가 이점과 함께). 그러나 성능 측면에서 빙산을 치는 타이타닉과 같은 수레를 가져 오십시오.

오래된 전용 str-> double 함수는 모두 30ms (또는 그 이상)에 10000 개의 구문 분석을 수행 할 수 있습니다. lexical_cast는 동일한 작업을 수행하는 데 650ms 정도 걸립니다.


출처가 없습니까? 직접 검색했습니다. boost.org/doc/libs/1_55_0/doc/html/boost_lexical_cast/…
Blake

0

내 문제:

  1. 로케일 독립 문자열을 double로 (소수 구분 기호는 항상 '.')
  2. 문자열 변환 실패시 오류 감지

내 솔루션 (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 ...이 솔루션을 얻는 데 꽤 오래 걸렸습니다. 그리고 나는 여전히 문자열 현지화 등에 대해 충분히 알지 못한다는 느낌을받습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.