Konwersja int do std :: string


143

Jaki jest najkrótszy sposób, najlepiej wbudowany, aby przekonwertować int na łańcuch? Odpowiedzi za pomocą STL i Boost będą mile widziane.



63
W C ++ 11 możesz użyć to_stringlikestd::string s = std::to_string(42)

5
Niech żyje C ++ 11 i to_string! :)
augustin

Odpowiedzi:


351

Możesz użyć std :: to_string w C ++ 11

int i = 3;
std::string str = std::to_string(i);

4
std :: to_string () nie działa w MinGW, jeśli kogoś to obchodzi.
Archie

3
@bparker Zgadza się, to chyba zostało naprawione w gcc 4.8.0. MinGW z najnowszym Code :: Blocks (13.12) nadal ma gcc 4.7.1.
Archie

47
#include <sstream>
#include <string>
const int i = 3;
std::ostringstream s;
s << i;
const std::string i_as_string(s.str());

36

boost::lexical_cast<std::string>(yourint) z boost/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:


15
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ń ...
rubenvb


Należy wziąć pod uwagę swoich odbiorców, jeśli nie mogą korzystać z funkcji Boost
Damian

5
„Odpowiedzi używające STL i Boost będą mile widziane”. - Uwzględniona publiczność
Conrad Jones

30

Dobrze znanym sposobem na to jest użycie operatora strumienia:

#include <sstream>

std::ostringstream s;
int i;

s << i;

std::string converted(s.str());

Oczywiście możesz uogólnić to dla dowolnego typu używając funkcji szablonu ^^

#include <sstream>

template<typename T>
std::string toString(const T& value)
{
    std::ostringstream oss;
    oss << value;
    return oss.str();
}

1
Uwaga: to wymaga #include <sstream>.
TechNyquist

@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 = new char[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.


14

Niestandardowa funkcja, ale jest zaimplementowana w większości popularnych kompilatorów:

int input = MY_VALUE;
char buffer[100] = {0};
int number_base = 10;
std::string output = itoa(input, buffer, number_base);

Aktualizacja

C ++ 11 wprowadził kilka std::to_stringprzeciążeń (zwróć uwagę, że domyślnie jest to base-10).


3
@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 );
    return 0;
}

1
@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>:

#include <sstream>

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



-3

Przypuśćmy, że tak integer = 0123456789101112. Teraz ta liczba całkowita może zostać przekonwertowana na łańcuch przez stringstreamklasę.

Oto kod w C ++:

   #include <bits/stdc++.h>
   using namespace std;
   int main()
   {
      int n,i;
      string s;
      stringstream st;
      for(i=0;i<=12;i++)
      {
        st<<i;
      }
      s=st.str();
      cout<<s<<endl;
      return 0;

    }

nie były podobne, ale pełniejsze odpowiedzi udzielone już wiele lat temu?
Walter

Tak, ale myślę, że ta odpowiedź jest idealna, ponieważ nie otrzymałem żadnej skutecznej odpowiedzi z poprzedniej.
Shawon
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.