Muszę przechowywać podwójną jako ciąg. Wiem, że mogę go użyć, printfjeśli chcę go wyświetlić, ale chcę go po prostu zapisać w zmiennej ciągu, aby móc później zapisać go na mapie (jako wartość , a nie klucz ).
Pytanie odpowiadające na twoje pytanie: dlaczego przechowujesz podwójną wartość w ciągu, aby zapisać ją na mapie? Czy jako klucza użyjesz podwójnej liczby łańcuchowej? Jeśli nie, dlaczego nie zostawić podwójnej postaci?
Matt McClellan
1
Ciekawy punkt. Używanie podwójnego klucza jako klucza mapy może jednak wiązać się z niebezpieczeństwem, ponieważ dokładne porównania wartości zmiennoprzecinkowych zawsze są. Indeksowanie reprezentacji ciągu pozwala uniknąć problemu.
Fred Larson
2
Po co to w ogóle konwertować? Zapisz go na mapie jako podwójny i unikaj konwersji na iz.
EvilTeach
3
To wciąż brzmi jak wezwanie do przedmiotów. Związek działałby. Każdy obiekt, aby wstawić do niego różne wartości i samemu zweryfikować.
EvilTeach
2
Mam tylko kilka par nazwa / wartość w pliku. Nie wymaga przedmiotów.
Myślę, że boost :: lexical_cast JEST prawie standardową metodą C ++, po prostu ładnie zapakowaną dla Ciebie. BTW, litb, masz tam drobną literówkę - "boot: lexical_cast".
Fred Larson
2
boost :: lexical_cast to nie tylko proste opakowanie wokół kodu stringstream. Wiele procedur konwersji jest zaimplementowanych w linii. Zgodnie z pomiarami wydajności na dole tej strony ( boost.org/doc/libs/1_47_0/libs/conversion/lexical_cast.htm ), boost :: lexical_cast jest szybszy niż używanie stringstreams i, w większości przypadków, szybszy niż scanf / printf
Ferruccio
1
@Ferr, kto powiedział, że to proste opakowanie? I dzięki za udostępnienie łącza, tak naprawdę nie sądzę, że było mniej lub bardziej prosty wrapper :)
Johannes Schaub - litb
27
nie zapomnij #include <sstream>o sposobie c ++ :)
VladL
3
Ze względu na dokumentację, jeśli tego nie zrobisz #include <sstream>, pojawi się błąd „niepełny typ jest niedozwolony”.
Trevor Sullivan
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);
Twój sposób C ++ nie zadziała, ponieważ operator <<zwraca std::ostream&zamiast a stringstream&.
Konrad Rudolph
Wygląda na to, że moje struny są trochę zardzewiałe, wolę stare sposoby. Naprawiono teraz (mam nadzieję).
Adam Rosenfield
Twój kod C z początku mnie wyrzucił. Nadal głosowałem za podaniem właściwych alternatyw.
Bill the Lizard
2
Głosuj za włączeniem metody C. po prostu wydaje mi się o wiele czystszy.
Nealon
11
Uznany za sposób C ++ 11. Jestem nowy w C ++ i nie zdawałem sobie sprawy, że istnieje to_stringfunkcja. Używam Microsoft Visual C ++ 2013.
Trevor Sullivan
123
Standardowa C ++ 11 sposób (jeśli nie dbają o format wyjściowy):
#include<string>auto str = std::to_string(42.5);
to_stringto nowa funkcja biblioteczna wprowadzona w N1803 (r0), N1982 (r1) i N2408 (r2) „ Prosty dostęp numeryczny ”. Istnieje również stodfunkcja wykonywania operacji odwrotnej.
Jeśli chcesz mieć inny format wyjściowy niż "%f", użyj metod snprintflub ostringstream, jak pokazano w innych odpowiedziach.
Oh tak kochanie. to_string i stod oba działają w Visual Studio 11.
BSalita
Ojej kochanie ... to_string nie działa w VisualStudio 2010): To albo nie wiem, co robię (bardzo możliwe)
chessofnerd
1
To powinno być wyższe, ponieważ jest bardziej nowoczesne!
gsamaras
1
Czy istnieje sposób, aby ta funkcja nie dodawała większej liczby miejsc po przecinku, niż potrzeba? Kiedy konwertuję dublet 8.0, otrzymam strunę "8.000000", podczas gdy "8"byłoby idealnie.
HelloGoodbye,
1
To nie działa dla małych liczb ... np: 1e-9produkuje0.000000
user3728501
24
Jeśli używasz C ++, unikaj sprintf. Nie jest napisane w C ++ i ma kilka problemów. Stringstreams to metoda z wyboru, najlepiej hermetyzowana, jak w Boost.LexicalCast, co można zrobić dość łatwo:
#include<boost/lexical_cast.hpp>#include<string>// In some function:double d =453.23;
std::string str = boost::lexical_cast<string>(d);
W obu przypadkach strpowinno być "453.23"później. LexicalCast ma pewne zalety, ponieważ zapewnia całkowitą transformację. Używa stringstreams wewnętrznie.
To nie jest odpowiedź, ale byłby bardzo przydatny komentarz do pytania.
Limited Atonement
6
Problem z lexical_cast polega na niemożności zdefiniowania precyzji. Zwykle, jeśli konwertujesz double na ciąg, dzieje się tak, ponieważ chcesz go wydrukować. Jeśli precyzja jest za duża lub za mała, wpłynie to na wynik.
Dla przypomnienia: w moim własnym kodzie preferuję snprintf (). Z tablicą char na lokalnym stosie nie jest to takie nieefektywne. (Cóż, może jeśli przekroczyłeś rozmiar tablicy i zapętlono, aby zrobić to dwukrotnie ...)
(Zapakowałem to również za pomocą vsnprintf (). Ale to kosztuje mnie trochę sprawdzenia typu. Yelp, jeśli chcesz kod ...)
Wspomniałem o printf, ponieważ wyszukiwanie w Google przyniosło kilka artykułów, które mówią, że należy zamienić podwójną na ciąg, którego używasz printf. Zakładają, że jedyne, co możesz zrobić, to drukowanie, co w moim przypadku jest fałszywe.
Bill the Lizard
dlaczego głosujesz -1? Myślę, że sprintf jest dobry. @BilltheLizard, sprint drukuje coś do znaku * nie ekranu. Ktoś odpowiedział c metoda nadal ma dużo głosów.
worldterminator
2
Normalnie dla tych operacji musisz użyć funkcji ecvt, fcvt lub 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
Odpowiedzi:
Sposób wzmocnienia (tm) :
Przez standard C ++ sposób:
Uwaga : nie zapomnij
#include <sstream>
źródło
#include <sstream>
o sposobie c ++ :)#include <sstream>
, pojawi się błąd „niepełny typ jest niedozwolony”.źródło
operator <<
zwracastd::ostream&
zamiast astringstream&
.to_string
funkcja. Używam Microsoft Visual C ++ 2013.Standardowa C ++ 11 sposób (jeśli nie dbają o format wyjściowy):
to_string
to nowa funkcja biblioteczna wprowadzona w N1803 (r0), N1982 (r1) i N2408 (r2) „ Prosty dostęp numeryczny ”. Istnieje równieżstod
funkcja wykonywania operacji odwrotnej.Jeśli chcesz mieć inny format wyjściowy niż
"%f"
, użyj metodsnprintf
lubostringstream
, jak pokazano w innych odpowiedziach.źródło
8.0
, otrzymam strunę"8.000000"
, podczas gdy"8"
byłoby idealnie.1e-9
produkuje0.000000
Jeśli używasz C ++, unikaj
sprintf
. Nie jest napisane w C ++ i ma kilka problemów. Stringstreams to metoda z wyboru, najlepiej hermetyzowana, jak w Boost.LexicalCast, co można zrobić dość łatwo:Stosowanie:
źródło
Możesz użyć std :: to_string w C ++ 11
źródło
std::to_string()
po prostu zwróciły 0,000000, a nie w formie naukowej.sprintf
jest w porządku, ale w C ++ lepszym, bezpieczniejszym i nieco wolniejszym sposobem konwersji jeststringstream
:Możesz także użyć Boost.LexicalCast :
W obu przypadkach
str
powinno być"453.23"
później. LexicalCast ma pewne zalety, ponieważ zapewnia całkowitą transformację. Używastringstream
s wewnętrznie.źródło
Spojrzałbym na C ++ String Toolkit Libary . Właśnie opublikowałem podobną odpowiedź w innym miejscu. Okazało się, że jest bardzo szybki i niezawodny.
źródło
Herb Sutter ma doskonały artykuł na temat formatowania ciągów . Polecam ją przeczytać. Mam związane ją przed na SO.
źródło
Problem z lexical_cast polega na niemożności zdefiniowania precyzji. Zwykle, jeśli konwertujesz double na ciąg, dzieje się tak, ponieważ chcesz go wydrukować. Jeśli precyzja jest za duża lub za mała, wpłynie to na wynik.
źródło
Możesz także użyć stringstream .
źródło
Heh, właśnie napisałem to (niezwiązane z tym pytaniem):
źródło
Możesz przeczytać mój wcześniejszy post na SO. (Wersja makro z tymczasowym obiektem ostringstream.)
Dla przypomnienia: w moim własnym kodzie preferuję snprintf (). Z tablicą char na lokalnym stosie nie jest to takie nieefektywne. (Cóż, może jeśli przekroczyłeś rozmiar tablicy i zapętlono, aby zrobić to dwukrotnie ...)
(Zapakowałem to również za pomocą vsnprintf (). Ale to kosztuje mnie trochę sprawdzenia typu. Yelp, jeśli chcesz kod ...)
źródło
Przyjrzyj się
sprintf()
i rodzinie.źródło
Normalnie dla tych operacji musisz użyć funkcji ecvt, fcvt lub gcvt:
Jako funkcja:
źródło
Możesz wypróbować bardziej kompaktowy styl:
źródło
Użyj
to_string()
.przykład:
uruchom go samodzielnie: http://ideone.com/7ejfaU
Te są również dostępne:
źródło
Możesz przekonwertować dowolną rzecz na cokolwiek za pomocą tej funkcji:
stosowanie :
źródło