Boost jest twoim przyjacielem, jeśli nie było prostego sposobu na zrobienie tego w Standard C ++ ... Oczywiście podoba mi się to lexical_cast, co przynosi, ale czuję, że Boost jest dość przesadą dla tego rodzaju zadań ...
@TechNyquist: Masz rację. Nie miał być kompilowalny, ale zmieniony!
neuro-
1
Więc nie chciałeś, żeby było to kompilowalne, ale tak naprawdę z dołączeniem jest :)
TechNyquist.
1
@TechNyquist: Tak, z niektórymi std::;)
neuro
16
Jeśli nie możesz używać std::to_stringz C ++ 11, możesz napisać to tak, jak jest zdefiniowane na cppreference.com:
std::string to_string( int value )
Przekształca podpisane całkowitą dziesiętną na sznurku z tej samej treści jak co std::sprintf(buf, "%d", value)przyniosłoby dla dostatecznie dużych buf.
Realizacja
#include<cstdio>#include<string>#include<cassert>
std::string to_string(int x ){int length = snprintf( NULL,0,"%d", x );
assert( length >=0);char* buf =newchar[length +1];
snprintf( buf, length +1,"%d", x );
std::string str( buf );delete[] buf;return str;}
Możesz z tym zrobić więcej. Po prostu użyj "%g"do konwersji float lub double na string, użyj "%x"do konwersji int na reprezentację szesnastkową i tak dalej.
@DevSolar: Powinieneś rozwinąć. Podano już przykład wzmocnienia. To rozwiązanie jest dostępne w większości kompilatorów, gdy boost nie jest zainstalowany (lub twoje wymagania zabraniają używania go z jakiegokolwiek powodu). Te ostreamprace, jak również, aż trzeba zapisać numer ciąg jako coś innego niż binarny, ósemkowy, lub w formacie szesnastkowym (np base-32).
Zac Howland,
3
Nie podoba mi się, gdy niestandardowe funkcje lubią itoa()lub stricmp()są podawane jako odpowiedź na cokolwiek .
DevSolar
6
Przepraszam, że uraziłem twoją wrażliwość, ale powiedziałem, że to niestandardowa funkcja w pierwszym zdaniu. Nie wspomniałem o tym, ale sprintfmogę również osiągnąć cel PO (chociaż nadal cierpi z powodu braku elastyczności, jeśli potrzebne jest coś innego niż wspólne liczby podstawowe).
Zac Howland,
1
Tak, powiedziałeś to, a ja nie przegłosowałem Twojej odpowiedzi, nawet jeśli bardzo mnie to nie chciało. Więc myślę, że jesteśmy kwita. ;-)
DevSolar
8
Poniższe makro nie jest tak kompaktowe, jak jednorazowe ostringstreamlubboost::lexical_cast .
Ale jeśli potrzebujesz wielokrotnie konwersji na ciąg w swoim kodzie, to makro jest bardziej eleganckie w użyciu niż bezpośrednia obsługa strumieni ciągów lub jawne rzutowanie za każdym razem.
Jest również bardzo wszechstronny, ponieważ konwertuje wszystko, co jest obsługiwane operator<<(), nawet w połączeniu.
Definicja:
#include<sstream>#define SSTR( x )dynamic_cast< std::ostringstream &>( \
( std::ostringstream()<< std::dec << x )).str()
Wyjaśnienie:
Jest std::decto sposób na przekształcenie anonimowości ostringstreamw rodzaj ogólny, wolny od skutków ubocznych, ostreamdzięki czemu operator<<()wyszukiwanie funkcji działa poprawnie dla wszystkich typów. (W przeciwnym razie będziesz miał kłopoty, jeśli pierwszy argument jest typem wskaźnikowym.)
dynamic_castZwraca wpisać plecami do ostringstreamtak można wywołać str()na nim.
Posługiwać się:
#include<string>int main(){int i =42;
std::string s1 = SSTR( i );int x =23;
std::string s2 = SSTR("i: "<< i <<", x: "<< x );return0;}
@rubenvb: Powiedz mi, jak zamienić to w szablon, a ja zaktualizuję wszystkie projekty C ++, w których
używałem
@rubenvb: Przepraszamy, to nie było tak jasne, jak powinno. Nie widzę sposobu, w jaki sposób mógłbym przekształcić to w szablon (używając C ++ 98) bez utraty możliwości łączenia łańcuchowego danych wyjściowych (jak w moim drugim przykładzie) lub konieczności wymyślenia zawiłego bałaganu do obsługi dowolna liczba parametrów i typów parametrów.
DevSolar,
@DevSolar: nie inline template<class T> std::string SSTR( T x ) { return dynamic_cast< std::ostringstream & >( (std::ostringstream() << std::dec << x) ).str() }zrobiłbyś? (Nie testowałem, ale zastanawiam się, co poszłoby nie tak i dlaczego?
rubenvb
@rubenvb: Zrobiłoby to dla osoby int(mój pierwszy przykład). Ale bez ostreamwidoczne dla kompilatora w main(jak to jest ukryty wewnątrz funkcji szablonu), będzie starał się patrzeć operator<<()na const char []moim drugim przykładzie - który będzie rechot. Wiem, że OP wymagał tylko rozszerzenia int, ale to bardziej ogólne makro jest tak przydatne (i właściwie dość rozpowszechnione), że pomyślałem, że umieściłem je tutaj.
DevSolar
Ze względu na wszechstronność preferuję funkcję szablonu. Dla łańcucha łańcuchowego, który może być obsługiwany w tej samej funkcji z odrobiną RTTI ...
neuro
2
Możesz użyć tej funkcji, aby przekonwertować intna std::stringafter w tym <sstream>:
to_string
likestd::string s = std::to_string(42)
Odpowiedzi:
Możesz użyć std :: to_string w C ++ 11
źródło
źródło
boost::lexical_cast<std::string>(yourint)
zboost/lexical_cast.hpp
Działa na wszystko dzięki obsłudze std :: ostream, ale nie jest tak szybka, jak na przykład
itoa
Wydaje się nawet, że jest szybszy niż stringstream lub scanf:
źródło
lexical_cast
, co przynosi, ale czuję, że Boost jest dość przesadą dla tego rodzaju zadań ...Dobrze znanym sposobem na to jest użycie operatora strumienia:
Oczywiście możesz uogólnić to dla dowolnego typu używając funkcji szablonu ^^
źródło
#include <sstream>
.std::
;)Jeśli nie możesz używać
std::to_string
z C ++ 11, możesz napisać to tak, jak jest zdefiniowane na cppreference.com:Realizacja
Możesz z tym zrobić więcej. Po prostu użyj
"%g"
do konwersji float lub double na string, użyj"%x"
do konwersji int na reprezentację szesnastkową i tak dalej.źródło
Niestandardowa funkcja, ale jest zaimplementowana w większości popularnych kompilatorów:
Aktualizacja
C ++ 11 wprowadził kilka
std::to_string
przeciążeń (zwróć uwagę, że domyślnie jest to base-10).źródło
ostream
prace, jak również, aż trzeba zapisać numer ciąg jako coś innego niż binarny, ósemkowy, lub w formacie szesnastkowym (np base-32).itoa()
lubstricmp()
są podawane jako odpowiedź na cokolwiek .sprintf
mogę również osiągnąć cel PO (chociaż nadal cierpi z powodu braku elastyczności, jeśli potrzebne jest coś innego niż wspólne liczby podstawowe).Poniższe makro nie jest tak kompaktowe, jak jednorazowe
ostringstream
lubboost::lexical_cast
.Ale jeśli potrzebujesz wielokrotnie konwersji na ciąg w swoim kodzie, to makro jest bardziej eleganckie w użyciu niż bezpośrednia obsługa strumieni ciągów lub jawne rzutowanie za każdym razem.
Jest również bardzo wszechstronny, ponieważ konwertuje wszystko, co jest obsługiwane
operator<<()
, nawet w połączeniu.Definicja:
Wyjaśnienie:
Jest
std::dec
to sposób na przekształcenie anonimowościostringstream
w rodzaj ogólny, wolny od skutków ubocznych,ostream
dzięki czemuoperator<<()
wyszukiwanie funkcji działa poprawnie dla wszystkich typów. (W przeciwnym razie będziesz miał kłopoty, jeśli pierwszy argument jest typem wskaźnikowym.)dynamic_cast
Zwraca wpisać plecami doostringstream
tak można wywołaćstr()
na nim.Posługiwać się:
źródło
inline template<class T> std::string SSTR( T x ) { return dynamic_cast< std::ostringstream & >( (std::ostringstream() << std::dec << x) ).str() }
zrobiłbyś? (Nie testowałem, ale zastanawiam się, co poszłoby nie tak i dlaczego?int
(mój pierwszy przykład). Ale bezostream
widoczne dla kompilatora wmain
(jak to jest ukryty wewnątrz funkcji szablonu), będzie starał się patrzećoperator<<()
naconst char []
moim drugim przykładzie - który będzie rechot. Wiem, że OP wymagał tylko rozszerzeniaint
, ale to bardziej ogólne makro jest tak przydatne (i właściwie dość rozpowszechnione), że pomyślałem, że umieściłem je tutaj.Możesz użyć tej funkcji, aby przekonwertować
int
nastd::string
after w tym<sstream>
:źródło
Możesz uwzględnić implementację itoa w swoim projekcie.
Oto itoa zmodyfikowana do pracy ze std :: string: http://www.strudel.org.uk/itoa/
źródło
Oto kolejny łatwy sposób konwersji int na string
możesz odwiedzić ten link, aby uzyskać więcej metod https://www.geeksforgeeks.org/what-is-the-best-way-in-c-to-convert-a-number-to-a-string/
źródło
Przypuśćmy, że tak
integer = 0123456789101112
. Teraz ta liczba całkowita może zostać przekonwertowana na łańcuch przezstringstream
klasę.Oto kod w C ++:
źródło