Конвертировать float в std :: string в C ++ - PullRequest
59 голосов
/ 24 января 2010

У меня есть значение с плавающей точкой, которое нужно поместить в std::string. Как мне преобразовать число с плавающей точкой в ​​строку?

float val = 2.5;
std::string my_val = val; // error here

Ответы [ 8 ]

109 голосов
/ 18 июня 2013

Начиная с C ++ 11, стандартная библиотека C ++ предоставляет функции std::to_string(arg) с различными поддерживаемыми типами для arg.

53 голосов
/ 24 января 2010

Если вы не беспокоитесь о производительности, используйте строковые потоки :

std::ostringstream ss;
ss << myFloat;
std::string s(ss.str());

Если с Boost все в порядке, lexical_cast <> - это удобная альтернатива:

std::string s = boost::lexical_cast<std::string>(myFloat);

Эффективными альтернативами являются, например, FastFormat или просто функции в стиле C.

15 голосов
/ 24 января 2010

Вы можете определить шаблон, который будет работать не только с двойными, но и с другими типами.

template <typename T> string tostr(const T& t) { 
   ostringstream os; 
   os<<t; 
   return os.str(); 
} 

Затем вы можете использовать его для других типов.

double x = 14.4;
int y = 21;

string sx = tostr(x);
string sy = tostr(y);
14 голосов
/ 11 февраля 2016

Важно
Прочитайте примечание в конце.

Быстрый ответ:
Используйте to_string(). (доступно начиная с c ++ 11)
пример:

#include <iostream>   
#include <string>  

using namespace std;
int main ()
{
    string pi = "pi is " + to_string(3.1415926);
    cout<< "pi = "<< pi << endl;

  return 0;
}

Запустите его самостоятельно: http://ideone.com/7ejfaU
Они также доступны:

string to_string (int val);
string to_string (long val);
string to_string (long long val);
string to_string (unsigned val);
string to_string (unsigned long val);
string to_string (unsigned long long val);
string to_string (float val);
string to_string (double val);
string to_string (long double val);

Важное примечание:
Как справедливо заметил @Michael Konečný, использование to_string() в лучшем случае рискованно, что может привести к неожиданным результатам.
От http://en.cppreference.com/w/cpp/string/basic_string/to_string:

С типами с плавающей запятой std::to_string может давать неожиданные результаты , поскольку число значащих цифр в возвращаемой строке может быть равно нулю, см. Пример.
Возвращаемое значение может значительно отличаться от того, что печатает std::cout по умолчанию, см. Пример. std::to_string полагается на текущую локаль для форматирования, и поэтому одновременные вызовы std::to_string из несколько потоков могут привести к частичной сериализации вызовов. C++17 std::to_chars обеспечивает более высокую производительность независимо от локали Альтернатива.

Лучшим способом было бы использовать stringstream, как и другие, такие как @dcp, продемонстрированный в его ответе .:

Эта проблема демонстрируется в следующем примере:
запустите пример самостоятельно: https://www.jdoodle.com/embed/v0/T4k

#include <iostream>
#include <sstream>
#include <string>

template < typename Type > std::string to_str (const Type & t)
{
  std::ostringstream os;
  os << t;
  return os.str ();
}

int main ()
{

  // more info : https://en.cppreference.com/w/cpp/string/basic_string/to_string
  double    f = 23.43;
  double    f2 = 1e-9;
  double    f3 = 1e40;
  double    f4 = 1e-40;
  double    f5 = 123456789;
  std::string f_str = std::to_string (f);
  std::string f_str2 = std::to_string (f2); // Note: returns "0.000000"
  std::string f_str3 = std::to_string (f3); // Note: Does not return "1e+40".
  std::string f_str4 = std::to_string (f4); // Note: returns "0.000000"
  std::string f_str5 = std::to_string (f5);

  std::cout << "std::cout: " << f << '\n'
    << "to_string: " << f_str << '\n'
    << "ostringstream: " << to_str (f) << "\n\n"
    << "std::cout: " << f2 << '\n'
    << "to_string: " << f_str2 << '\n'
    << "ostringstream: " << to_str (f2) << "\n\n"
    << "std::cout: " << f3 << '\n'
    << "to_string: " << f_str3 << '\n'
    << "ostringstream: " << to_str (f3) << "\n\n"
    << "std::cout: " << f4 << '\n'
    << "to_string: " << f_str4 << '\n'
    << "ostringstream: " << to_str (f4) << "\n\n"
    << "std::cout: " << f5 << '\n'
    << "to_string: " << f_str5 << '\n'
    << "ostringstream: " << to_str (f5) << '\n';

  return 0;
}

вывод:

std::cout: 23.43
to_string: 23.430000
ostringstream: 23.43

std::cout: 1e-09
to_string: 0.000000
ostringstream: 1e-09

std::cout: 1e+40
to_string: 10000000000000000303786028427003666890752.000000
ostringstream: 1e+40

std::cout: 1e-40
to_string: 0.000000
ostringstream: 1e-40

std::cout: 1.23457e+08
to_string: 123456789.000000
ostringstream: 1.23457e+08 
4 голосов
/ 27 марта 2017

Вы можете использовать std :: to_string в C ++ 11

float val = 2.5;
std::string my_val = std::to_string(val);
2 голосов
/ 24 марта 2019

Используйте std::to_chars, как только ваша стандартная библиотека предоставит его:

std::array<char, 32> buf;
auto result = std::to_chars(buf.data(), buf.data() + buf.size(), val);
if (result.ec == std::errc()) {
  auto str = std::string(buf.data(), result.ptr - buf.data());
  // use the string
} else {
  // handle the error
}

Преимущества этого метода:

  • Он не зависит от локали и предотвращает ошибки при записи данных в форматы, такие как JSON, для которых требуется '.' в виде десятичной точки
  • Обеспечивает кратчайшее десятичное представление с гарантиями туда и обратно
  • Он потенциально более эффективен, чем другие стандартные методы, потому что он не использует локаль и не требует выделения

К сожалению, std::to_string имеет ограниченную полезность с плавающей запятой, поскольку использует фиксированное представление, округляя маленькие значения до нуля и создавая длинные строки для больших значений, например,

auto s1 = std::to_string(1e+40);
// s1 == 10000000000000000303786028427003666890752.000000

auto s2 = std::to_string(1e-40);
// s2 == 0.000000

C ++ 20 может получить более удобный std::format API с теми же преимуществами, что и std::to_chars, если предложение по стандартам P0645 будет одобрено.

1 голос
/ 24 января 2010

Если вы беспокоитесь о производительности, посмотрите библиотеку Boost :: lexical_cast .

0 голосов
/ 03 ноября 2013

Этот урок дает простое, но элегантное решение, которое я расшифрую:

#include <sstream>
#include <string>
#include <stdexcept>

class BadConversion : public std::runtime_error {
public:
  BadConversion(std::string const& s)
    : std::runtime_error(s)
    { }
};

inline std::string stringify(double x)
{
  std::ostringstream o;
  if (!(o << x))
    throw BadConversion("stringify(double)");
  return o.str();
}
...
std::string my_val = stringify(val);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...