Jaki jest najłatwiejszy sposób konwersji z int
odpowiednika string
w C ++. Mam świadomość dwóch metod. Czy jest jakiś łatwiejszy sposób?
(1)
int a = 10;
char *intStr = itoa(a);
string str = string(intStr);
(2)
int a = 10;
stringstream ss;
ss << a;
string str = ss.str();
c++
string
int
type-conversion
Nemo
źródło
źródło
itoa()
potrzeba trzech parametrów.Odpowiedzi:
C ++ 11 wprowadza się
std::stoi
(i warianty dla każdego typu) i numerycznychstd::to_string
, odpowiedniki Catoi
iitoa
, ale wyrażone w perspektywiestd::string
.jest zatem najkrótszym sposobem, jaki mogę wymyślić. Możesz nawet pominąć nazywanie typu za pomocą
auto
słowa kluczowego:Uwaga: patrz [string.conversions] ( 21.5 w n3242 )
źródło
to_string
nie jest członkiemstd
fix: stackoverflow.com/questions/12975341/…g++ -std=c++11 someFile.cc
std
każdego kompilatora, którego znam, z wyjątkiem jednego.Error : No instance of overloaded function "std::to_string" matches the argument list
używam VS2010 c ++string s = to_string((_ULonglong)i);
Rozpoczynając dyskusję z @ v.oddou kilka lat później, C ++ 17 w końcu zapewnił sposób na wykonanie pierwotnie opartego na makro rozwiązania typu agnostyk (zachowane poniżej) bez przechodzenia przez brzydotę makro.
Stosowanie:
Oryginalna odpowiedź:
Ponieważ „konwersja ... na ciąg” jest powtarzającym się problemem, zawsze definiuję makro SSTR () w centralnym nagłówku moich źródeł C ++:
Użycie jest tak proste, jak mogłoby być:
Powyższe jest kompatybilne z C ++ 98 (jeśli nie możesz używać C ++ 11
std::to_string
) i nie wymaga żadnych zewnętrznych programów (jeśli nie możesz użyć Boostlexical_cast<>
); oba te rozwiązania mają jednak lepszą wydajność.źródło
dynamic_cast
ale używam clang do kompilacji, więc to narzeka. Jeśli tylko pominędynamic_cast
to, to dobrze się kompiluje; jaki celdynamic_cast
służy w tym przypadku? Już tworzymyostringstream
, więc po co to obsadzać?ostringstream
wywołaliśmyoperator<<()
go, który zwracaostream &
- dla którego.str()
nie jest zdefiniowany. Naprawdę zastanawiam się, jak clang sprawiłby, że działałby bez obsady (lub dlaczego generuje błąd). Ten konstrukt jest publikowany w wielu miejscach i od ponad dekady korzystam z niego w wielu różnych kompilatorach, w tym MSVC, GCC i XLC, więc jestem raczej zaskoczony, że bawi go to.do { } while( 0 )
nic by nie dodało. W wersjach 2. i 3. prawdopodobnie masz rację - można to zrobić za pomocą rzutowania statycznego, a być może jeden z kreatorów szablonów może zaproponować „ładniejszy” interfejs. Ale jak powiedziałem, nie jest to w żadnym wypadku wynalazek. Rozejrzyj się, to makro (makro!) Jest dość wszechobecne. To jest przypadek samej POLA. Mogę się z tym trochę zabawić, aby uczynić go bardziej „usprawnionym”.Zwykle używam następującej metody:
Jest to szczegółowo opisane tutaj .
źródło
ss
musisz toss.clear()
zrobić. Widziałem nieoczekiwane wyniki bez tej inicjalizacji.clear()
nowo utworzonegoostringstream
obiektu.clear()
resetuje flagi błędu / eof i nie został jeszcze wygenerowany żaden błąd / eof.NumberToString(23213.123)
produkuje23213.1
podczas gdystd::to_string(23213.123)
produkuje23213.123000
Co się tam dzieje?Prawdopodobnie najczęstszym łatwym sposobem jest zawijanie drugiego wyboru w szablonie o nazwie
lexical_cast
, takim jak ten w Boost , więc twój kod wygląda następująco:Jedną z zalet tego jest to, że obsługuje również inne obsady (np. Działa również w przeciwnym kierunku).
Zauważ też, że chociaż Boost lexical_cast zaczynał jako pisanie do strumienia tekstowego, a następnie wypakowywanie go ze strumienia, teraz ma kilka dodatków. Przede wszystkim dodano specjalizacje dla kilku rodzajów, więc dla wielu popularnych typów jest to znacznie szybsze niż przy użyciu ciągu znaków. Po drugie, teraz sprawdza wynik, więc (na przykład), jeśli przekształcisz ciąg
int
znaków w ciąg znaków, może zgłosić wyjątek, jeśli ciąg znaków zawiera coś, czego nie można przekonwertować na ciąg znakówint
(np.1234
Powiedzie się, ale123abc
zwróci) .Począwszy od C ++ 11, istnieje
std::to_string
funkcja przeciążona dla typów całkowitych, więc możesz użyć kodu takiego jak:Standard określa je jako równoważne temu konwersję z
sprintf
(stosując specyfikator konwersji, który odpowiada podanemu typ obiektu, na przykład%d
zaint
), w buforze o odpowiedniej wielkości, a następnie stworzeniestd::string
zawartości tego buforu.źródło
Jeśli masz zainstalowany Boost (co powinieneś):
źródło
Byłoby łatwiej za pomocą stringstreams:
Lub wykonaj funkcję:
źródło
Nie wiem o tym w czystym C ++. Ale mała modyfikacja tego, o czym wspomniałeś
powinien działać i jest dość krótki.
źródło
itoa()
nie jest standardową funkcją!Możesz użyć
std::to_string
dostępne w C ++ 11, zgodnie z sugestią Matthieu M .:Lub, jeśli wydajność jest krytyczna (na przykład, jeśli robisz dużo konwersji), można skorzystać
fmt::format_int
z {} fmt biblioteki przekonwertować liczbę całkowitą dostd::string
:Lub ciąg C:
Ten ostatni nie dokonuje żadnych dynamicznych alokacji pamięci i jest ponad 10 razy szybszy niż
std::to_string
w testach Boost Karma. Zobacz Szybka konwersja liczb całkowitych na ciąg w C ++ uzyskać więcej informacji, .Pamiętaj, że oba są bezpieczne dla wątków.
W przeciwieństwie
std::to_string
,fmt::format_int
nie wymaga C ++ 11 i działa z dowolnym kompilatorem C ++.Oświadczenie: Jestem autorem biblioteki {fmt}.
źródło
c_str()
zwraca wskaźnik do bufora zadeklarowanego wewnątrzfmt::FormatInt
klasy - więc zwrócony wskaźnik będzie nieprawidłowy w średnik - patrz także stackoverflow.com/questions/4214153/lifetime-of-temporariesstd::string::c_str()
(a więc nazewnictwa). Jeśli chcesz użyć go poza pełnym wyrażeniem, skonstruuj obiekt.FormatInt f(42);
Następnie możesz go używaćf.c_str()
bez niebezpieczeństwa zniszczenia.sprintf()
jest całkiem dobry do konwersji formatu. Następnie możesz przypisać wynikowy ciąg C do ciągu C ++, tak jak w 1.źródło
NULL
zerowym rozmiarem, aby uzyskać niezbędny rozmiar bufora.snprintf
(zwróć uwagę na przedrostek SNP ) isprintf
(zwróć uwagę na przedrostek SP ). Przekazujesz rozmiar temu pierwszemu, uważając, aby się nie przepełnić, jednak ten drugi nie zna wielkości bufora i dlatego może się przepełnić.snprintf
najpierw nazwać wariant, asprintf
potem wariant. Ponieważ rozmiar bufora jest już znany, wywołaniesprintf
staje się całkowicie bezpieczne.Najpierw obejmują:
Następnie dodaj metodę:
Użyj następującej metody:
lub
źródło
Używanie strumienia ciągów do konwersji liczb jest niebezpieczne!
Zobacz http://www.cplusplus.com/reference/ostream/ostream/operator%3C%3C/, gdzie informuje, że
operator<<
wstawia sformatowane dane wyjściowe.W zależności od bieżących ustawień regionalnych liczba całkowita większa niż 3 cyfry może zostać przekształcona na ciąg 4 cyfr, dodając dodatkowy separator tysięcy.
Np.
int = 1000
Może być konwertowany na ciąg1.001
. Może to spowodować, że operacje porównania w ogóle nie będą działać.Tak więc zdecydowanie polecam korzystanie z tego
std::to_string
sposobu. Jest łatwiej i robi to, czego oczekujesz.Zaktualizowano (patrz komentarze poniżej) :
źródło
std::to_string
używa również bieżących ustawień regionalnych (patrz en.cppreference.com/w/cpp/string/basic_string/to_string , sekcja „Notatki”). Prawie wszystkie standardowe narzędzia (od strumieni ciągówsprintf
, ale takżesscanf
itp.) Używają bieżących ustawień regionalnych. Nie zdawałem sobie z tego sprawy aż do niedawna, kiedy mocno mnie uderzyło. Obecnie używa rzeczy domowej roboty, nie jest to trudne.W przypadku C ++ 98 istnieje kilka opcji:
boost/lexical_cast
Zwiększenie nie jest częścią biblioteki C ++, ale zawiera wiele przydatnych rozszerzeń bibliotek.
Jeśli chodzi o środowisko wykonawcze,
lexical_cast
operacja zajmuje około 80 mikrosekund (na moim komputerze) przy pierwszej konwersji, a następnie znacznie przyspiesza, jeśli zostanie wykonana nadmiarowo.itoa
Oznacza to, że
gcc
/g++
nie można skompilować kodu przy użyciuitoa
.Brak środowiska wykonawczego do zgłoszenia. Nie mam zainstalowanego programu Visual Studio, który podobno jest w stanie skompilować
itoa
.sprintf
sprintf
jest standardową funkcją biblioteki C, która działa na łańcuchach C i jest doskonale poprawną alternatywą.stdio.h
Nagłówek może nie być konieczne. Jeśli chodzi o środowisko wykonawcze,sprintf
operacja zajmuje około 40 mikrosekund (na moim komputerze) przy pierwszej konwersji, a następnie znacznie przyspiesza, jeśli zostanie wykonana nadmiarowo.stringstream
Jest to główny sposób konwersji liczb całkowitych na ciągi znaków w bibliotece C ++ i odwrotnie. Istnieją podobne funkcje siostrzane,
stringstream
które dodatkowo ograniczają zamierzone użycie strumienia, takie jakostringstream
. Użycie wostringstream
szczególności mówi czytelnikowi twojego kodu, że<<
zasadniczo zamierzasz korzystać z operatora. Ta funkcja jest wszystkim, co jest szczególnie potrzebne do konwersji liczby całkowitej na ciąg. Zobacz to pytanie, aby uzyskać bardziej szczegółową dyskusję.Jeśli chodzi o środowisko wykonawcze,
ostringstream
operacja zajmuje około 71 mikrosekund (na moim komputerze), a następnie znacznie przyspiesza, jeśli jest wykonywana nadmiarowo, ale nie o tyle, co poprzednie funkcje .Oczywiście istnieją inne opcje i możesz nawet zawinąć jedną z nich we własną funkcję, ale oferuje to analityczne spojrzenie na niektóre z popularnych.
źródło
C ++ 17 zapewnia std :: to_chars jako wydajniejszą alternatywę niezależną od ustawień regionalnych.
źródło
Dość łatwo jest dodać cukier syntaktyczny, który pozwala komponować struny w locie w sposób podobny do strumienia
Teraz możesz dołączyć, co chcesz (pod warunkiem, że operator
<< (std::ostream& ..)
jest dla niego zdefiniowany)strmake()
i używać go zamiaststd::string
.Przykład:
źródło
EDYTOWANE. Jeśli potrzebujesz szybkiej konwersji liczby całkowitej ze stałą liczbą cyfr na znak * uzupełniony lewy „0” , jest to przykład architektury little-endian (wszystkie x86, x86_64 i inne):
Jeśli konwertujesz dwucyfrowy numer:
Jeśli konwertujesz trzycyfrową liczbę:
Jeśli konwertujesz czterocyfrową liczbę:
I tak dalej do siedmiocyfrowych liczb. W tym przykładzie
n
podana jest liczba całkowita. Po konwersji można wyświetlić reprezentację ciągu jako(char*)&s
:UWAGA: Jeśli potrzebujesz go w kolejności bajtów big-endian, chociaż go nie testowałem, ale oto przykład: dla liczby trzycyfrowej jest to
int32_t s = 0x00303030 | (n/100)<< 24 | (n/10%10)<<16 | (n%10)<<8;
dla liczb czterocyfrowych (łuk 64-bitowy):int64_t s = 0x0000000030303030 | (n/1000)<<56 | (n/100%10)<<48 | (n/10%10)<<40 | (n%10)<<32;
Myślę, że powinno działać.źródło
Posługiwać się:
źródło
Używam:
Działa na moich kompilatorach g ++ dla Windows i Linux.
źródło
sprintf
jest dobrze znany do wstawiania dowolnych danych do ciągu o wymaganym formacie.Możesz przekonwertować
char *
tablicę na ciąg, jak pokazano w trzecim wierszu.źródło
To zadziałało dla mnie -
Mój kod:
źródło
stringstream
?std::to_string()
using namespace std;
:)C ++ 11 wprowadzony
std::to_string()
dla typów numerycznych:źródło
Posługiwać się:
źródło
źródło
Jeśli używasz MFC , możesz użyć
CString
:źródło
źródło
Możesz teraz użyć
to_string(5)
.źródło
std
przestrzeni nazw też nie jest czymś, co powinieneś zrobić. Poza tym nie wygląda na_MAX_INT_DIG
to, że jest standardowym makrem, więc jeśli zostanie źle zdefiniowany, ten kod ma ogromny potencjał do wywołania niezdefiniowanego zachowania. -1Myślę, że korzystanie
stringstream
jest dość łatwe:źródło
Algorytm typu licznika służy do konwersji na ciąg znaków. Technikę tę dostałem od programowania komputerów Commodore 64 . Jest także dobry do programowania gier.
Bierzesz liczbę całkowitą i bierzesz każdą cyfrę ważoną potęgami 10. Załóżmy, że liczba całkowita wynosi 950.
Jeśli liczba całkowita jest równa lub większa niż 100 000, to odejmij 100 000 i zwiększ licznik w ciągu [000000];
rób to dalej, aż nie będzie więcej liczb na pozycji 100 000. Upuść kolejną potęgę dziesięciu.
Jeśli liczba całkowita jest równa lub większa niż 10 000, to odejmij 10 000 i zwiększ licznik w ciągu w pozycji [„000000”] + 1 pozycja;
rób to dalej, aż nie będzie więcej liczb na pozycji 10.000.
Upuść kolejną potęgę dziesięciu
Wiem, że 950 jest zbyt mały, aby go użyć jako przykładu, ale mam nadzieję, że wpadłeś na ten pomysł.
źródło