Мне нужно хранить двойной как строка. Я знаю, что могу использовать, printfесли хочу отобразить его, но я просто хочу сохранить его в строковой переменной, чтобы потом сохранить его на карте (как значение , а не ключ ).
Вопрос для ответа на ваш вопрос: почему вы храните двойное значение в строке, чтобы сохранить его на карте? Собираетесь ли вы использовать строковое двойное в качестве ключа? Если нет, то почему бы не оставить двойной как есть?
Мэтт Макклеллан
1
Интересный момент. Однако использование double в качестве ключа карты может быть сопряжено с опасностью, поскольку точные сравнения значений с плавающей запятой всегда есть. Индексирование по строковому представлению устраняет проблему.
Фред Ларсон
2
Зачем конвертировать это вообще? Храните его на карте как двойное и избегайте конвертации в и из.
EvilTeach
3
Это все еще звучит как призыв к объектам. Союз будет работать. Каждый объект для вставки различных значений в него, и он сам проверяется.
EvilTeach
2
У меня есть только несколько пар имя / значение в файле. Это не требует объектов.
Я думаю, что boost :: lexical_cast в значительной степени является стандартным способом C ++, просто прекрасно упакованным для вас. Кстати, у вас есть небольшая опечатка - boot: lexical_cast.
Фред Ларсон
2
boost :: lexical_cast - это не просто оболочка для кода с потоком строк. Многие из процедур преобразования реализованы встроенными. Согласно измерениям производительности в нижней части этой страницы ( boost.org/doc/libs/1_47_0/libs/conversion/lexical_cast.htm ), boost :: lexical_cast быстрее, чем использование stringstream, и, в большинстве случаев, быстрее, чем scanf / printf
Ферруччо
1
@ Ферр, кто сказал, что это простая обертка? И спасибо за предоставленную ссылку, я на самом деле так думаю , что это было более или менее простой оберткой :)
Johannes Schaub - LITB
27
не забудьте #include <sstream>для пути с ++ :)
VladL
3
Ради документации, если вы этого не сделаете #include <sstream>, вы получите ошибку «неполный тип не допускается».
Тревор Салливан
194
// 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 ++ не будет работать, потому что operator <<возвращает std::ostream&скорее, чем stringstream&.
Конрад Рудольф
Кажется, мои струнные потоки немного ржавые, я предпочитаю старые способы. Исправлено сейчас (надеюсь).
Адам Розенфилд
Ваш код на C сначала сбил меня с толку. Я все еще поддерживал тебя за то, что ты дал правильные альтернативы.
Билл Ящерица
2
upvote для включения пути C. просто кажется мне намного чище.
Нилон
11
Голосование за C ++ 11. Я новичок в C ++, и не понял, что там была to_stringфункция. Я использую Microsoft Visual C ++ 2013.
Тревор Салливан
123
Стандарт C ++ 11 способ (если вы не заботитесь о формате вывода):
#include<string>auto str = std::to_string(42.5);
to_stringэто новая библиотечная функция, представленная в N1803 (r0), N1982 (r1) и N2408 (r2) « Простой числовой доступ ». Есть также stodфункция для выполнения обратной операции.
Если вы хотите использовать другой формат вывода "%f", используйте методы snprintfили, ostringstreamкак показано в других ответах.
о да, детка. to_string и stod обе работают в Visual Studio 11.
BSalita
О, дорогой, детка ... to_string не работает в VisualStudio 2010): Это, или я не знаю, что я делаю (очень возможно)
chessofnerd
1
Это должно быть выше, так как это более современно!
gsamaras
1
Есть ли способ заставить эту функцию не добавлять больше десятичных дробей, чем необходимо? Когда я конвертирую двойное, 8.0это дает мне строку"8.000000" , хотя "8"все будет в порядке.
Здравствуйте, до свидания,
1
Это не работает для небольших чисел ... например: 1e-9производит0.000000
пользователь3728501
24
Если вы используете C ++, избегайте sprintf. Это не-C ++ y и имеет несколько проблем. Stringstream - это метод выбора, предпочтительно инкапсулированный, как в 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 имеет некоторые преимущества в том, что он обеспечивает завершение преобразования. Он использует stringstreams внутри.
Это не ответ, но сделал бы очень полезный комментарий по этому вопросу.
Ограниченное искупление
6
Проблема с lexical_cast заключается в невозможности определить точность. Обычно, если вы конвертируете double в строку, это потому, что вы хотите распечатать ее. Если точность слишком велика или слишком мала, это повлияет на ваш результат.
Для записи: в моем собственном коде я предпочитаю snprintf (). С массивом char в локальном стеке это не так неэффективно. (Ну, может быть, если вы превысили размер массива и зациклились, чтобы сделать это дважды ...)
(Я также обернул это через vsnprintf (). Но это стоит мне некоторой проверки типа. Yelp, если вы хотите код ...)
Я упомянул printf, потому что googling нашел кучу статей, в которых говорится, что для преобразования из двойного в строку вы используете printf. Они предполагают, что единственное, что вы можете сделать, - это печатать, что в моем случае неверно.
Билл Ящерица
почему ты голосуешь -1? Я думаю, что спринтф это хорошо. @BilltheLizard, sprint печатает что-то на символе *, а не на экране. Кто-то ответил c метод все еще получил много голосов.
определитель мира
2
Обычно для этих операций вы должны использовать функции 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);return0;}Output:1365.251.37e+003
Ответы:
Способ повышения (тм) :
В Standard C ++ способ:
Примечание : не забудьте
#include <sstream>
источник
#include <sstream>
для пути с ++ :)#include <sstream>
, вы получите ошибку «неполный тип не допускается».источник
operator <<
возвращаетstd::ostream&
скорее, чемstringstream&
.to_string
функция. Я использую Microsoft Visual C ++ 2013.Стандарт C ++ 11 способ (если вы не заботитесь о формате вывода):
to_string
это новая библиотечная функция, представленная в N1803 (r0), N1982 (r1) и N2408 (r2) « Простой числовой доступ ». Есть такжеstod
функция для выполнения обратной операции.Если вы хотите использовать другой формат вывода
"%f"
, используйте методыsnprintf
или,ostringstream
как показано в других ответах.источник
8.0
это дает мне строку"8.000000"
, хотя"8"
все будет в порядке.1e-9
производит0.000000
Если вы используете C ++, избегайте
sprintf
. Это не-C ++ y и имеет несколько проблем. Stringstream - это метод выбора, предпочтительно инкапсулированный, как в Boost.LexicalCast, который можно сделать довольно легко:Использование:
источник
Вы можете использовать std :: to_string в C ++ 11
источник
std::to_string()
просто вернули 0,000000, а не в научной форме.sprintf
все в порядке, но в C ++ лучший, более безопасный и немного медленный способ преобразованияstringstream
:Вы также можете использовать Boost.LexicalCast :
В обоих случаях
str
должно быть"453.23"
потом. LexicalCast имеет некоторые преимущества в том, что он обеспечивает завершение преобразования. Он используетstringstream
s внутри.источник
Я бы посмотрел на C ++ String Toolkit Libary . Просто опубликовал аналогичный ответ в другом месте. Я нашел это очень быстро и надежно.
источник
У Херба Саттера есть отличная статья о форматировании строк . Я рекомендую прочитать это. Я связал это раньше на SO.
источник
Проблема с lexical_cast заключается в невозможности определить точность. Обычно, если вы конвертируете double в строку, это потому, что вы хотите распечатать ее. Если точность слишком велика или слишком мала, это повлияет на ваш результат.
источник
Вы также можете использовать stringstream .
источник
Хех, я только что написал это (не имеет отношения к этому вопросу):
источник
Вы можете прочитать мои предыдущие публикации на SO. (Макро-версия с временным объектом ostringstream.)
Для записи: в моем собственном коде я предпочитаю snprintf (). С массивом char в локальном стеке это не так неэффективно. (Ну, может быть, если вы превысили размер массива и зациклились, чтобы сделать это дважды ...)
(Я также обернул это через vsnprintf (). Но это стоит мне некоторой проверки типа. Yelp, если вы хотите код ...)
источник
Взгляните и на
sprintf()
семью.источник
Обычно для этих операций вы должны использовать функции ecvt, fcvt или gcvt:
Как функция:
источник
Вы можете попробовать более компактный стиль:
источник
Использование
to_string()
.пример :
запустите его сами: http://ideone.com/7ejfaU
Они также доступны:
источник
Вы можете конвертировать любую вещь во что угодно, используя эту функцию:
использование :
источник