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.