Najprostszym sposobem na konwersję int na string w C ++


1573

Jaki jest najłatwiejszy sposób konwersji z intodpowiednika stringw 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();

4
Myślę, że obie metody, które podałeś, są dobrym rozwiązaniem. zależy to od kontekstu, w którym musisz to zrobić. Jeśli już pracujesz ze strumieniami, na przykład czytając lub zapisując plik, druga metoda jest najlepsza. Jeśli potrzebujesz przekazać int jako ciąg do argumentu funkcji, itoa może być łatwym sposobem. Ale w większości przypadków konwersja int na łańcuch występuje podczas obsługi plików, więc strumienie są odpowiednie.
Charles Brunet,

41
Jak w ogóle działa dla Ciebie opcja 1? Rozumiem, że itoa()potrzeba trzech parametrów.
b1nary.atr0phy 10.04.2013

1
itoa będzie szybszy niż ekwiwalent strumienia. Istnieją również sposoby ponownego wykorzystania bufora ciągów za pomocą metody itoa (unikanie przydziałów sterty, jeśli często generujesz ciągi, np. W przypadku niektórych szybko aktualizowanych danych liczbowych). Alternatywnie możesz wygenerować niestandardowy streambuf, aby zmniejszyć część kosztów alokacji itp. Konstruowanie strumienia w pierwszej kolejności również nie jest przedsięwzięciem o niskich kosztach.
Pete

6
@Pete: Kiedy zaczniesz się martwić, co jest szybsze, powinieneś spojrzeć na stackoverflow.com/questions/4351371/...
Ben Voigt

20
Zauważ, że itoa () nie jest częścią standardu i dlatego użycie go powoduje, że Twój kod nie jest przenośny, ponieważ nie wszystkie kompilatory go obsługują. W przypadku Linuksa z pewnością nie działa, chyba że używasz czegoś innego niż GCC, który nie obsługuje tej funkcji. Jeśli masz C ++ 0x, idź z tym, co sugerował @ Matthieu w swojej odpowiedzi. Jeśli tak nie jest, przejdź do stringstream, ponieważ jest to dobrze obsługiwana funkcja, a twój kod powinien być kompatybilny z każdym kompilatorem C ++. Alternatywnie zawsze możesz skorzystać z sprintf ().
rbaleksandar

Odpowiedzi:


2098

C ++ 11 wprowadza się std::stoi(i warianty dla każdego typu) i numerycznych std::to_string, odpowiedniki C atoii itoa, ale wyrażone w perspektywiestd::string .

#include <string> 

std::string s = std::to_string(42);

jest zatem najkrótszym sposobem, jaki mogę wymyślić. Możesz nawet pominąć nazywanie typu za pomocąauto słowa kluczowego:

auto s = std::to_string(42);

Uwaga: patrz [string.conversions] ( 21.5 w n3242 )


199
to_stringnie jest członkiem stdfix: stackoverflow.com/questions/12975341/…
Ben

36
Lub w zależności od kompilatora, po prostu ustaw odpowiedni standard językowy:g++ -std=c++11 someFile.cc
Thomas M. DuBuisson

12
@ Steve: tak powinno być. Jest członkiem stdkażdego kompilatora, którego znam, z wyjątkiem jednego.
Mooing Duck

5
@Matthiew M. Używam tego samego, co sugerujesz, ale otrzymuję ten błąd: Error : No instance of overloaded function "std::to_string" matches the argument list używam VS2010 c ++

19
@Flying: w VS2010 musisz jawnie rzutować liczbę całkowitą konwersji na jeden z następujących typów [_Longlong, _ULonglong, long double]; tj .:string s = to_string((_ULonglong)i);
Zac

184

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.

// variadic template
template < typename... Args >
std::string sstr( Args &&... args )
{
    std::ostringstream sstr;
    // fold expression
    ( sstr << std::dec << ... << args );
    return sstr.str();
}

Stosowanie:

int i = 42;
std::string s = sstr( "i is: ", i );
puts( sstr( i ).c_str() );

Foo x( 42 );
throw std::runtime_error( sstr( "Foo is '", x, "', i is ", i ) );

Oryginalna odpowiedź:

Ponieważ „konwersja ... na ciąg” jest powtarzającym się problemem, zawsze definiuję makro SSTR () w centralnym nagłówku moich źródeł C ++:

#include <sstream>

#define SSTR( x ) static_cast< std::ostringstream & >( \
        ( std::ostringstream() << std::dec << x ) ).str()

Użycie jest tak proste, jak mogłoby być:

int i = 42;
std::string s = SSTR( "i is: " << i );
puts( SSTR( i ).c_str() );

Foo x( 42 );
throw std::runtime_error( SSTR( "Foo is '" << x << "', i is " << i ) );

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ć Boost lexical_cast<>); oba te rozwiązania mają jednak lepszą wydajność.


2
Nie jestem zbyt obeznany, dynamic_castale używam clang do kompilacji, więc to narzeka. Jeśli tylko pominę dynamic_castto, to dobrze się kompiluje; jaki cel dynamic_castsłuży w tym przypadku? Już tworzymy ostringstream, więc po co to obsadzać?
Mathew

2
@Mateusz: Link w mojej odpowiedzi prowadzi do szczegółowego opisu każdej części konstrukcji. Podczas tworzenia a ostringstreamwywołaliśmy operator<<()go, który zwraca ostream &- 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.
DevSolar

5
Właśnie przybyłem na imprezę z ciekawości i przegłosowałem. Powód: za dużo głosów na rozwiązanie, które nie jest eleganckie i prawdopodobnie wolne. 1. wykorzystanie makr. Nie marszczę systematycznie żadnego makra, ale ten jest za krótki, a klienci końcowi zawsze obawiają się powtórzenia argumentu, oprócz strachu przed niezabezpieczonymi makrami wieloliniowymi. (nie chroniony przez do {} while (0)) 2. dynamic_cast. wygląda na to, że potrzebujesz tutaj tylko static_cast, chyba że chcesz stwierdzić, że biblioteka rzeczywiście została zaimplementowana, jak masz nadzieję. w takim przypadku powinieneś użyć boost :: polymorphic_downcast.
v.oddou

2
@ v.oddou: Oczywiście możesz swobodnie krytykować. Ale 1. jest niepoprawny - makro jest pojedynczą instrukcją, 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”.
DevSolar,

1
@ v.oddou: Zobacz, co znalazłem wśród rzeczy, które przyniósł nam C ++ 17. :-) Mam nadzieję, że podoba Ci się zaktualizowana odpowiedź.
DevSolar

109

Zwykle używam następującej metody:

#include <sstream>

template <typename T>
  std::string NumberToString ( T Number )
  {
     std::ostringstream ss;
     ss << Number;
     return ss.str();
  }

Jest to szczegółowo opisane tutaj .


2
Przed użyciem ssmusisz to ss.clear()zrobić. Widziałem nieoczekiwane wyniki bez tej inicjalizacji.
lifebalance

14
@lifebalance: Nigdy nie widziałem takiego zachowania.
Rasoul,

18
@lifebalance: Nie potrzebujesz clear()nowo utworzonego ostringstreamobiektu. clear()resetuje flagi błędu / eof i nie został jeszcze wygenerowany żaden błąd / eof.
Remy Lebeau,

2
@Rasoul NumberToString(23213.123)produkuje 23213.1podczas gdy std::to_string(23213.123)produkuje 23213.123000Co się tam dzieje?
Killzone Kid

1
@KillzoneKid Jest tak, ponieważ ostd std jest stanowy (oznacza to, że każda poprzednia zmiana stanu jest zachowana, podobnie jak liczba cyfr dziesiętnych), podczas gdy ta metoda zaczyna się od stanu domyślnego.
xryl669

85

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:

int a = 10;
string s = lexical_cast<string>(a);

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 intznakó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ów int(np. 1234Powiedzie się, ale123abc zwróci) .

Począwszy od C ++ 11, istnieje std::to_stringfunkcja przeciążona dla typów całkowitych, więc możesz użyć kodu takiego jak:

int a = 20;
std::string s = std::to_string(a);
// or: auto s = std::to_string(a);

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 %dza int), w buforze o odpowiedniej wielkości, a następnie stworzenie std::stringzawartości tego buforu.


2
Fajnie, wolę odpowiedź Kevina, choć pokazuje on dołączenie i przestrzeń nazw. Tylko niewielka przeszkoda. :) Dobra robota jednak!
Jason R. Mick

4
Powiedziałbym, że jest to właściwy sposób, jeśli nie masz obsługi języka C ++ 11.
Alex

40

Jeśli masz zainstalowany Boost (co powinieneś):

#include <boost/lexical_cast.hpp>

int num = 4;
std::string str = boost::lexical_cast<std::string>(num);

4
Uzgodniono instalację doładowania. Myślę, że częściej niż często formatuje się ciąg. W tym celu wolę boost :: format, np. Format („% 02d”, liczba) .str ()
Werner Erasmus

28

Byłoby łatwiej za pomocą stringstreams:

#include <sstream>

int x = 42;          // The integer
string str;          // The string
ostringstream temp;  // 'temp' as in temporary
temp << x;
str = temp.str();    // str is 'temp' as string

Lub wykonaj funkcję:

#include <sstream>

string IntToString(int a)
{
    ostringstream temp;
    temp << a;
    return temp.str();
}

18

Nie wiem o tym w czystym C ++. Ale mała modyfikacja tego, o czym wspomniałeś

string s = string(itoa(a));

powinien działać i jest dość krótki.


55
itoa()nie jest standardową funkcją!
rysownik

4
@cartoonist: Więc o co chodzi?
user541686,

20
Ta funkcja nie jest zdefiniowana w ANSI-C i C ++. Dlatego nie jest obsługiwany przez niektóre kompilatory, takie jak g ++.
rysownik

17

Możesz użyć std::to_stringdostępne w C ++ 11, zgodnie z sugestią Matthieu M .:

std::to_string(42);

Lub, jeśli wydajność jest krytyczna (na przykład, jeśli robisz dużo konwersji), można skorzystać fmt::format_intz {} fmt biblioteki przekonwertować liczbę całkowitą do std::string:

fmt::format_int(42).str();

Lub ciąg C:

fmt::format_int f(42);
f.c_str();

Ten ostatni nie dokonuje żadnych dynamicznych alokacji pamięci i jest ponad 10 razy szybszy niż std::to_stringw 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}.


2
Byłem ciekawy twierdzenia, że ​​nie mam żadnego dynamicznego przydziału pamięci, pozostając bezpieczny na wątki (ponownie uczestnik), więc przeczytałem twój kod - c_str()zwraca wskaźnik do bufora zadeklarowanego wewnątrz fmt::FormatIntklasy - więc zwrócony wskaźnik będzie nieprawidłowy w średnik - patrz także stackoverflow.com/questions/4214153/lifetime-of-temporaries
Soren

1
Tak, takie samo zachowanie jak w przypadku std::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.
vitaut

1
Dostaję coś dziwnego, gdy próbuję przekonwertować z int na string za pomocą std :: to_string (num). Jeśli przechowuję wynik w zmiennej i próbuję uzyskać do niej dostęp jak stringNum [1] lub stringNum [n], gdy n wzrasta, otrzymuję śmieci.
user8951490,

1
To zdecydowanie właściwa odpowiedź na to pytanie: wydajny i standardowy kod, który nie jest stanowy.
xryl669,

16

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.


1
Hej, tak. Jednak zwykle polegam na snprintf () i przyjaciołach dla jakichkolwiek konsekwencji podczas obsługi ciągów C.
1986

1
@MatthieuM. Twój komentarz dodatkowo potwierdza, że ​​nie jesteś. Jeśli wynik został obcięty z powodu tego limitu, zwracaną wartością jest liczba znaków (z wyłączeniem kończącego bajtu zerowego), które zostałyby zapisane w końcowym ciągu, gdyby było wystarczająco dużo miejsca. Dlatego zwracana wartość rozmiaru lub większa oznacza, że ​​dane wyjściowe zostały obcięte. Więc wywołujesz go z NULLzerowym rozmiarem, aby uzyskać niezbędny rozmiar bufora.
user1095108

2
@ user1095108: Myślę, że się mylisz snprintf(zwróć uwagę na przedrostek SNP ) i sprintf(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ć.
Matthieu M.,

1
Chodzi o to, aby snprintfnajpierw nazwać wariant, a sprintfpotem wariant. Ponieważ rozmiar bufora jest już znany, wywołanie sprintfstaje się całkowicie bezpieczne.
user1095108

1
@ user1095108 Ah, tak. Jeśli pierwszy bufor do snprintf jest niewystarczający, zwracana wartość mówi ci, co byłoby wystarczające. Nadal używałbym snprintf do drugiego wywołania, ponieważ poleganie na implementacjach dopasowania sprintf i snprintf jest niepotrzebnie niebezpieczne.
mabraham

11

Najpierw obejmują:

#include <string>
#include <sstream>

Następnie dodaj metodę:

template <typename T>
string NumberToString(T pNumber)
{
 ostringstream oOStrStream;
 oOStrStream << pNumber;
 return oOStrStream.str();
}

Użyj następującej metody:

NumberToString(69);

lub

int x = 69;
string vStr = NumberToString(x) + " Hello word!."

10

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 = 1000Może być konwertowany na ciąg 1.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_stringsposobu. Jest łatwiej i robi to, czego oczekujesz.

Zaktualizowano (patrz komentarze poniżej) :

C ++ 17 zapewnia std::to_charswyższą wydajność niezależną od ustawień lokalnych


2
Zgadzam się, że jest to poważny problem, jeśli musisz wymieniać dane. Niestety std::to_stringuż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ów sprintf, ale także sscanfitp.) 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.
Bert Bril

W powyższym linku jest również statet, że C ++ 17 zapewnia std :: to_chars jako bardziej wydajną, niezależną od ustawień regionalnych alternatywę.
YesThatIsMyName

Niestety utknąłem w C ++ 11 na nadchodzące lata (już całkiem dobra poprawa, na szczęście).
Bert Bril

1
from_chars i to_chars byłyby idealne, ale niestety nie oferowały wariantu wchar_t.
gast128 10.10.19

8

W przypadku C ++ 98 istnieje kilka opcji:

boost/lexical_cast

Zwiększenie nie jest częścią biblioteki C ++, ale zawiera wiele przydatnych rozszerzeń bibliotek.

lexical_castSzablon funkcja oferuje wygodny i spójną formę do wspierania wspólnych konwersji do iz dowolnych typów, gdy są one reprezentowane jako tekst.
- Dokumentacja doładowania

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

int main() {
    int x = 5;
    std::string x_str = boost::lexical_cast<std::string>(x);
    return 0;
}

Jeśli chodzi o środowisko wykonawcze, lexical_castoperacja zajmuje około 80 mikrosekund (na moim komputerze) przy pierwszej konwersji, a następnie znacznie przyspiesza, jeśli zostanie wykonana nadmiarowo.


itoa

Ta funkcja nie jest zdefiniowana w ANSI-C i nie jest częścią C ++, ale jest obsługiwana przez niektóre kompilatory.
- cplusplus.com

Oznacza to, że gcc/ g++nie można skompilować kodu przy użyciu itoa.

#include <stdlib.h>

int main() {
    int x = 5;
    char * x_str = new char[2];
    x_str = itoa(x, x_str, 10); // base 10
    return 0;
}

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ą.

Tworzy ciąg z tym samym tekstem, który zostałby wydrukowany, gdyby w printf użyto formatu, ale zamiast go wydrukować, zawartość jest przechowywana jako ciąg C w buforze wskazanym przez str.
- cplusplus.com

#include <stdio.h>

int main() {
    int x = 5;
    char * x_str = new char[2];
    int chars_written = sprintf(x_str, "%d", x);
    return 0;
}

stdio.hNagłówek może nie być konieczne. Jeśli chodzi o środowisko wykonawcze, sprintfoperacja 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, stringstreamktóre dodatkowo ograniczają zamierzone użycie strumienia, takie jak ostringstream. Użycie w ostringstreamszczegó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ę.

#include <sstream>
#include <string>

int main() {
    int x = 5;
    std::ostringstream stream;
    stream << x;
    std::string x_str = stream.str();
    return 0;
}

Jeśli chodzi o środowisko wykonawcze, ostringstreamoperacja 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.


Dzięki za opiekę (użytkownicy C ++ 98)
A. B

@AB Nie mogę uwierzyć, że nadal jest jakiś użytkownik C ++ 98.
Kotauskas,

@VladislavToncharov Kiedy twoja praca polega wyłącznie na wspieraniu starszego sprzętu i kodu, wrzucasz stare rzeczy, stosując świeższe standardy branżowe. Latem pisałem kod w Pythonie 2.3.
Joshua Detwiler

@JoshuaDetwiler Och, zapomniałem o tym, przepraszam.
Kotauskas

4

C ++ 17 zapewnia std :: to_chars jako wydajniejszą alternatywę niezależną od ustawień regionalnych.


3

Dość łatwo jest dodać cukier syntaktyczny, który pozwala komponować struny w locie w sposób podobny do strumienia

#include <string>
#include <sstream>

struct strmake {
    std::stringstream s;
    template <typename T> strmake& operator << (const T& x) {
        s << x; return *this;
    }   
    operator std::string() {return s.str();}
};

Teraz możesz dołączyć, co chcesz (pod warunkiem, że operator << (std::ostream& ..)jest dla niego zdefiniowany) strmake()i używać go zamiast std::string.

Przykład:

#include <iostream>

int main() {
    std::string x =
      strmake() << "Current time is " << 5+5 << ":" << 5*5 << " GST";
    std::cout << x << std::endl;
}

2

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:

int32_t s = 0x3030 | (n/10) | (n%10) << 8;

Jeśli konwertujesz trzycyfrową liczbę:

int32_t s = 0x303030 | (n/100) | (n/10%10) << 8 | (n%10) << 16;

Jeśli konwertujesz czterocyfrową liczbę:

int64_t s = 0x30303030 | (n/1000) | (n/100%10)<<8 | (n/10%10)<<16 | (n%10)<<24;

I tak dalej do siedmiocyfrowych liczb. W tym przykładzie npodana jest liczba całkowita. Po konwersji można wyświetlić reprezentację ciągu jako (char*)&s:

std::cout << (char*)&s << std::endl;

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ć.


2
Co z kolejnością bajtów?
shjeff,

Czy to nie jest niezdefiniowane zachowanie spowodowane aliasingiem wskaźnika?
dgnuff

1
@shjeff dzięki za komentarz, dodałem notatkę na temat endianizmu do odpowiedzi.
Alek

@dgnuff dziękuję za zwrócenie na to uwagi, chociaż nie miałem z tym problemu, masz rację. Dzięki, nieznacznie zmodyfikowałem odpowiedź, aby była zgodna ze ścisłymi zasadami aliasowania.
Alek

1

Posługiwać się:

#define convertToString(x) #x

int main()
{
    convertToString(42); // Returns const char* equivalent of 42
}

3
Działa tylko z liczbami literalnymi, nie ocenia zawartości zmiennej, chociaż czasem jest przydatny.
Wolf

Dobrze. Ale zdecydowanie przydatna w czasie
maverick9888

1
Działa tylko w czasie kompilacji z liczbami stałych literalnych, myślę, że OP prosi o konwersję dynamiczną, używając zmiennych całkowitych
Ing. Gerardo Sánchez

0

Używam:

int myint = 0;
long double myLD = 0.0;

string myint_str = static_cast<ostringstream*>(&(ostringstream() << myint))->str();
string myLD_str = static_cast<ostringstream*>(&(ostringstream() << myLD))->str();

Działa na moich kompilatorach g ++ dla Windows i Linux.


0

Oto kolejny prosty sposób

char str[100];
sprintf(str, "%d", 101);
string s = str;

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.


0

To zadziałało dla mnie -

Mój kod:

#include <iostream>
using namespace std;

int main()
{
    int n = 32;
    string s = to_string(n);
    cout << "string: " + s  << endl;
    return 0;
}

Zasadniczo za pomocą czego? stringstream?
Peter Mortensen

@PeterMortensen Spójrz uważnie, tostd::to_string()
Kotauskas

mam using namespace std;:)
Gonçalo Garrido

0

C ++ 11 wprowadzony std::to_string()dla typów numerycznych:

int n = 123; // Input, signed/unsigned short/int/long/long long/float/double
std::string str = std::to_string(n); // Output, std::string

4
Cześć! Czy możesz dodać wyjaśnienie, dlaczego i jak stanowi to odpowiedź na pytanie?
anothernode

0

Posługiwać się:

#include<iostream>
#include<string>

std::string intToString(int num);

int main()
{
    int integer = 4782151;

    std::string integerAsStr = intToString(integer);

    std::cout << "integer = " << integer << std::endl;
    std::cout << "integerAsStr = " << integerAsStr << std::endl;

    return 0;
}

std::string intToString(int num)
{
    std::string numAsStr;

    while (num)
    {
        char toInsert = (num % 10) + 48;
        numAsStr.insert(0, 1, toInsert);

        num /= 10;
    }
    return numAsStr;
}

1
Całkowicie zawodzi dla n ≤0
Toby Speight

-1
string number_to_string(int x) {

    if (!x)
        return "0";

    string s, s2;
    while(x) {
        s.push_back(x%10 + '0');
        x /= 10;
    }
    reverse(s.begin(), s.end());
    return s;
}

1
Dziękujemy za ten fragment kodu, który może zapewnić ograniczoną krótkotrwałą pomoc. Właściwe wyjaśnienie znacznie poprawiłoby jego długoterminową wartość, pokazując, dlaczego jest to dobre rozwiązanie problemu, i uczyniłoby to bardziej użytecznym dla przyszłych czytelników z innymi podobnymi pytaniami. Proszę edytować swoją odpowiedź dodać kilka wyjaśnień, w tym założeń już wykonanych.
Toby Speight,

Całkowicie zawodzi dla n ≤0
Toby Speight

Dodaj komentarze, wyjaśnij swoją odpowiedź, przeczytaj, jak odpowiedzieć .
Aksen P

-1

Jeśli używasz MFC , możesz użyć CString:

int a = 10;
CString strA;
strA.Format("%d", a);

8
Należy pamiętać, że jest to rozszerzenie tylko do Microsoft: msdn.microsoft.com/en-us/library/ms174288.aspx
JonnyJD

1
Podoba mi się pomysł CString :: Format (). Niestety, to tylko nieprzenośne stwardnienie rozsiane.
Nick

1
Zaktualizowałem moją odpowiedź, aby zawierała informacje z twojego komentarza @JonnyJD, ponieważ wciąż jestem za nią oceniany 5 lat później ..
Tur1ng

-2
char * bufSecs = new char[32];
char * bufMs = new char[32];
sprintf(bufSecs, "%d", timeStart.elapsed()/1000);
sprintf(bufMs, "%d", timeStart.elapsed()%1000);

12
wyciek pamięci, -1 ode mnie
paulm

Pachnie to jak przepełnienie bufora.
Kotauskas,

-2
namespace std
{
    inline string to_string(int _Val)
    {   // Convert long long to string
        char _Buf[2 * _MAX_INT_DIG];
        snprintf(_Buf, "%d", _Val);
        return (string(_Buf));
    }
}

Możesz teraz użyć to_string(5).


10
Chociaż to rozwiązanie działa, jest bardzo odradzane! Nazwy zaczynające się od podkreślenia i dużej litery są zarezerwowane dla kompilatora, nigdy nie powinieneś ich używać. Wstrzykiwanie funkcji do stdprzestrzeni nazw też nie jest czymś, co powinieneś zrobić. Poza tym nie wygląda na _MAX_INT_DIGto, że jest standardowym makrem, więc jeśli zostanie źle zdefiniowany, ten kod ma ogromny potencjał do wywołania niezdefiniowanego zachowania. -1
iFreilicht

6
Co to jest _MAX_INT_DIG i dlaczego jest podwojony?
paulm

-2

Myślę, że korzystanie stringstreamjest dość łatwe:

 string toString(int n)
 {
     stringstream ss(n);
     ss << n;
     return ss.str();
 }

 int main()
 {
    int n;
    cin >> n;
    cout << toString(n) << endl;
    return 0;
 }

Zostało to wspomniane w pytaniu i niestety jest dość powolne.
Kotauskas,

-3

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

  • Powtórz wzór

Wiem, że 950 jest zbyt mały, aby go użyć jako przykładu, ale mam nadzieję, że wpadłeś na ten pomysł.


Opis algorytmu nie jest zbyt pomocny, zamiast pokazywać przykład w kodzie.
cdeerinck
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.