Pregunta std :: string para flotar o duplicar


Estoy tratando de convertir std::string a float/double. Lo intenté:

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

Pero siempre regresa a cero. ¿Alguna otra manera?


75
2018-06-18 13:15


origen


Respuestas:


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

Lo hace por mí, es una sintaxis C ++ válida para convertir una cadena en un doble.

Puede hacerlo con stringstream o boost :: lexical_cast, pero estos vienen con una penalización de rendimiento.


Ahaha, tienes un proyecto de Qt ...

QString winOpacity("0.6");
double temp = winOpacity.toDouble();

Nota extra:
Si los datos de entrada son const char*, QByteArray::toDouble será más rápido.


103
2018-06-18 13:25



La biblioteca estándar (C ++ 11) ofrece la funcionalidad deseada con std::stod :

std::string  s  = "0.6"
std::wstring ws = "0.7"
double d  = std::stod(s);
double dw = std::stod(ws);

Supongo que la Biblioteca estándar también se convierte internamente, pero de esta forma hace que el código sea más limpio. Generalmente para la mayoría de otros tipos básicos, vea <string>. También hay algunas características nuevas para las cadenas C. Ver <stdlib.h> 


78
2017-10-17 10:41



El reparto léxico es muy bueno.

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

27
2018-06-18 13:21



Puedes usar 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;
   }

Uso:

double number= StringToNumber<double>("0.6");

14
2018-06-18 13:27



Sí, con un elenco léxico. Use un operador de cadena de caracteres y <<, o use Boost, ya lo han implementado.

Tu propia versión podría verse así:

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

  os << x;
  os >> ret;

  return ret;  
}

9
2018-06-18 13:19



Puede usar el impulso del lanzamiento léxico:

#include <boost/lexical_cast.hpp>

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

Nota: boost :: lexical_cast lanza una excepción por lo que debe estar preparado para tratar con ella cuando pase el valor no válido, intente pasar la cadena ("xxx")


7
2018-06-18 13:22



Si no quiere arrastrar todo el impulso, vaya con strtod(3) de <cstdlib> - ya devuelve un doble.

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

Productos:

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

Por qué atof () no funciona ... ¿en qué plataforma / compilador estás?


4
2018-06-18 13:23



Tuve el mismo problema en Linux

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

funciona.


3
2018-02-19 09:50



Esta respuesta está respaldando en sus comentarios. Tengo profundas sospechas de que simplemente no muestra el resultado correctamente.

Me pasó exactamente lo mismo una vez. Pasé todo un día tratando de descubrir por qué estaba obteniendo un mal valor en un int de 64 bits, solo para descubrir que printf estaba ignorando el segundo byte. No se puede simplemente pasar un valor de 64 bits a printf como si fuera un int.


1
2018-06-18 13:38