Как я могу преобразовать двойной в строку в C++?

Мне нужно хранить двойной как строка. Я знаю, что могу использовать printf если бы я хотел отобразить его, но я просто хочу сохранить его в строковой переменной, чтобы позднее я мог сохранить его на карте (как значение, а не ключ).

19 ответов

Решение

Способ повышения (тм):

std::string str = boost::lexical_cast<std::string>(dbl);

Стандартный C++ способ:

std::ostringstream strs;
strs << dbl;
std::string str = strs.str();

Примечание: не забудьте #include <sstream>

// The C way:
char buffer[32];
snprintf(buffer, sizeof(buffer), "%g", myDoubleVar);

// The C++03 way:
std::ostringstream sstream;
sstream << myDoubleVar;
std::string varAsString = sstream.str();

// The C++11 way:
std::string varAsString = std::to_string(myDoubleVar);

// The boost way:
std::string varAsString = boost::lexical_cast<std::string>(myDoubleVar);

Стандартный C++11 способ (если вас не интересует формат вывода):

#include <string>

auto str = std::to_string(42.5); 

to_string это новая библиотечная функция, представленная в N1803 (r0), N1982 (r1) и N2408 (r2) " Простой числовой доступ ". Есть также stod Функция для выполнения обратной операции.

Если вы хотите иметь другой формат вывода, чем "%f", использовать snprintf или же ostringstream методы, как показано в других ответах.

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

double d = 3.0;
std::string str = std::to_string(d);

Если вы используете C++, избегайте sprintf, Это не-C++y и имеет несколько проблем. Stringstreams - метод выбора, предпочтительно инкапсулированный как в Boost.LexicalCast, который можно сделать довольно легко:

template <typename T>
std::string to_string(T const& value) {
    stringstream sstr;
    sstr << value;
    return sstr.str();
}

Использование:

string s = to_string(42.5);

sprintf все в порядке, но в C++ лучший, более безопасный и немного медленный способ преобразования stringstream:

#include <sstream>
#include <string>

// In some function:
double d = 453.23;
std::ostringstream os;
os << d;
std::string str = os.str();

Вы также можете использовать Boost.LexicalCast:

#include <boost/lexical_cast.hpp>
#include <string>

// In some function:
double d = 453.23;
std::string str = boost::lexical_cast<string>(d);

В обоих случаях str должно быть "453.23" после этого. LexicalCast имеет некоторые преимущества в том, что он обеспечивает завершение преобразования. Оно использует stringstreamвнутренне.

Я бы посмотрел на C++ String Toolkit Libary. Просто опубликовал аналогичный ответ в другом месте. Я нашел это очень быстро и надежно.

#include <strtk.hpp>

double pi = M_PI;
std::string pi_as_string  = strtk::type_to_string<double>( pi );

У Херба Саттера есть отличная статья о форматировании строк. Я рекомендую прочитать это. Я связал это раньше на SO.

Проблема с lexical_cast заключается в невозможности определить точность. Обычно, если вы конвертируете double в строку, это потому, что вы хотите распечатать ее. Если точность слишком велика или слишком мала, это повлияет на ваш результат.

Обычно для этих операций вы должны использовать функции ecvt, fcvt или gcvt:

/* gcvt example */
#include <stdio.h>
#include <stdlib.h>

main ()
{
  char buffer [20];
  gcvt (1365.249,6,buffer);
  puts (buffer);
  gcvt (1365.249,3,buffer);
  puts (buffer);
  return 0;
}

Output:
1365.25
1.37e+003   

Как функция:

void double_to_char(double f,char * buffer){
  gcvt(f,10,buffer);
}

Хех, я только что написал это (не имеет отношения к этому вопросу):

string temp = "";
stringstream outStream;
double ratio = (currentImage->width*1.0f)/currentImage->height;
outStream << " R: " << ratio;
temp = outStream.str();

/* rest of the code */

Вы также можете использовать stringstream.

Взгляни на sprintf() и семья.

Вы можете прочитать мою предыдущую публикацию на SO. (Макро-версия с временным объектом ostringstream.)

Для записи: в моем собственном коде я предпочитаю snprintf (). С массивом char в локальном стеке это не так неэффективно. (Ну, может быть, если вы превысили размер массива и зациклились, чтобы сделать это дважды...)

(Я также обернул это через vsnprintf (). Но это стоит мне некоторой проверки типа. Yelp, если вы хотите код...)

Обратите внимание, что строка - это просто представление типа double, и преобразование ее обратно в double может не привести к тому же значению. Также обратите внимание, что преобразование строки по умолчанию может обрезать преобразование до определенной точности. Стандартным способом C++ вы можете контролировать точность следующим образом:

      #include <sstream>
#include <math.h>
#include <iostream>
#include <iomanip>

int main()
{
    std::ostringstream sout;
    sout << M_PI << '\n';
    sout << std::setprecision(99) << M_PI << '\n';
    sout << std::setprecision(3) << M_PI << '\n';
    sout << std::fixed; //now the setprecision() value will look at the decimal part only.
    sout << std::setprecision(3) << M_PI << '\n';
    std::cout << sout.str();
}

который даст вам результат

      3.14159                                                                                                                                                                            
3.141592653589793115997963468544185161590576171875                                                                                                                                 
3.14                                                                                                                                                                               
3.142  

Использование to_string(),
пример:

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

Вы можете преобразовать любую вещь во что угодно, используя эту функцию:

template<class T = std::string, class U>
T to(U a) {
    std::stringstream ss;
    T ret;
    ss << a;
    ss >> ret;
    return ret;
};

использование:

std::string str = to(2.5);
double d = to<double>("2.5");

Вы можете попробовать более компактный стиль:

std::string number_in_string;

double number_in_double;

std::ostringstream output;

number_in_string = (dynamic_cast< std::ostringstream*>(&(output << number_in_double <<

std::endl)))->str(); 

C++17 представил: std::to_chars, std::to_chars_result — cppreference.com

       std::to_chars_result to_chars( char* first, char* last, float       value,
                               std::chars_format fmt, int precision );
std::to_chars_result to_chars( char* first, char* last, double      value,
                               std::chars_format fmt, int precision );
std::to_chars_result to_chars( char* first, char* last, long double value,
                               std::chars_format fmt, int precision );

Которые обеспечивают быстрый низкоуровневый способ преобразования с плавающей запятой в строку с некоторым уровнем управления форматом. Это должно быть быстро, так как распределение не выполняется, быстрее должна выполняться только пользовательская реализация для конкретного сценария.

С++ 20 представил простую в использовании строку формата высокого уровня (эквивалент библиотеки fmt):

std::format — cppreference.com

станд::формат

       template< class... Args >
std::string format( /*format_string<Args...>*/ fmt, Args&&... args );

template< class... Args >
std::wstring format( /*wformat_string<Args...>*/ fmt, Args&&... args );

template< class... Args >
std::string format( const std::locale& loc,
                    /*format_string<Args...>*/ fmt, Args&&... args );

template< class... Args >
std::wstring format( const std::locale& loc,
                     /*wformat_string<Args...>*/ fmt, Args&&... args );

Что довольно приятно и удобно. Тогда должно быть быстрееsprintf.

Другие вопросы по тегам