Conversion d'un int en std :: string

143

Quel est le moyen le plus court, de préférence en ligne, pour convertir un int en chaîne? Les réponses utilisant stl et boost seront les bienvenues.

Amir Rachum
la source
63
En C ++ 11, vous pouvez utiliser to_stringcommestd::string s = std::to_string(42)
5
Vive le C ++ 11 et to_string! :)
augustin

Réponses:

351

Vous pouvez utiliser std :: to_string en C ++ 11

int i = 3;
std::string str = std::to_string(i);
Yochai Timmer
la source
4
std :: to_string () ne fonctionne pas dans MinGW, si quelqu'un s'en soucie.
Archie
3
@bparker Oui, ça a été corrigé dans gcc 4.8.0 je suppose. MinGW avec le dernier Code :: Blocks (13.12) a toujours 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());
Benoit
la source
36

boost::lexical_cast<std::string>(yourint) de boost/lexical_cast.hpp

Fonctionne pour tout avec le support std :: ostream, mais n'est pas aussi rapide que, par exemple, itoa

Il semble même être plus rapide que stringstream ou scanf:

ltjax
la source
15
Boost est votre ami, s'il n'y avait pas de moyen simple de faire cela en C ++ standard ... j'aime bien sûr ce qui lexical_castapporte, mais je pense que Boost est assez exagéré pour ce genre de tâches ...
rubenvb
2
Overkill? Basé sur quoi? boost.org/doc/libs/1_53_0/doc/html/boost_lexical_cast/…
Catskul
Devrait considérer votre public s'il ne peut pas utiliser Boost
Damian
5
"Les réponses utilisant stl et boost seront les bienvenues." - Public considéré
Conrad Jones
30

Eh bien, le moyen bien connu de le faire consiste à utiliser l'opérateur de flux:

#include <sstream>

std::ostringstream s;
int i;

s << i;

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

Bien sûr, vous pouvez le généraliser pour tout type en utilisant une fonction de modèle ^^

#include <sstream>

template<typename T>
std::string toString(const T& value)
{
    std::ostringstream oss;
    oss << value;
    return oss.str();
}
neuro
la source
1
Remarque: cela nécessite #include <sstream>.
TechNyquist
@TechNyquist: Vous avez raison. Pas censé être compilable, mais changé!
neuro
1
Donc, vous ne vouliez pas que ce soit compilable, mais en fait avec l'inclusion, c'est :)
TechNyquist
1
@TechNyquist: Oui, avec certains std::;)
neuro
16

Si vous ne pouvez pas utiliser à std::to_stringpartir de C ++ 11, vous pouvez l'écrire tel qu'il est défini sur cppreference.com:

std::string to_string( int value ) Convertit un entier décimal signé en une chaîne avec le même contenu que ce std::sprintf(buf, "%d", value)qui produirait un buf suffisamment grand.

la mise en oeuvre

#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;
}

Vous pouvez en faire plus. Utilisez simplement "%g"pour convertir float ou double en chaîne, utilisez "%x"pour convertir int en représentation hexadécimale, et ainsi de suite.

user2622016
la source
14

Fonction non standard, mais implémentée sur les compilateurs les plus courants:

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

Mettre à jour

C ++ 11 a introduit plusieurs std::to_stringsurcharges (notez qu'il est par défaut base-10).

Zac Howland
la source
3
@DevSolar: Vous devriez élaborer. L'exemple du boost avait déjà été donné. Cette solution est disponible sur la plupart des compilateurs lorsque boost n'est pas installé (ou que vos exigences vous interdisent de l'utiliser pour quelque raison que ce soit). Cela ostreamfonctionne aussi bien, jusqu'à ce que vous ayez besoin de sauvegarder la chaîne de nombres sous un format autre qu'un format binaire, octal ou hexadécimal (par exemple base-32).
Zac Howland
3
Je n'aime pas quand des fonctions non standard aiment itoa()ou stricmp()sont données comme réponse à quoi que ce soit .
DevSolar
6
Désolé d'offenser votre sensibilité, mais j'ai déclaré que c'était une fonction non standard dans la première phrase. Je ne l'ai pas mentionné, mais je sprintfpeux également atteindre l'objectif de l'OP (bien que souffre toujours du manque de flexibilité si autre chose que les numéros de base communs est nécessaire).
Zac Howland
1
Oui, vous l'avez dit, et je n'ai pas voté contre votre réponse, même si cela me démangeait de le faire. Alors je pense que nous sommes égaux. ;-)
DevSolar
8

La macro suivante n'est pas aussi compacte qu'un ostringstreamou un boost::lexical_cast.

Mais si vous avez besoin d'une conversion en chaîne à plusieurs reprises dans votre code, cette macro est plus élégante à utiliser que la gestion directe des flux de chaînes ou du cast explicite à chaque fois.

Il est également très polyvalent, car il convertit tout ce qui est pris en charge operator<<(), même en combinaison.

Définition:

#include <sstream>

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

Explication:

Il std::decs'agit d'un moyen sans effet secondaire de transformer l'anonymat ostringstreamen un générique ostreamafin que la operator<<()recherche de fonction fonctionne correctement pour tous les types. (Vous avez des problèmes sinon si le premier argument est un type pointeur.)

Le dynamic_castrenvoie le type à pour ostringstreamque vous puissiez l'appeler str().

Utilisation:

#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;
}
DevSolar
la source
1
@rubenvb: Vous me dites comment transformer cela en modèle et je mettrai à jour tous les projets C ++ dans lesquels j'utilise cette construction.
DevSolar
@rubenvb: Désolé, ce n'était pas aussi clair qu'il aurait dû l'être. Je ne vois pas comment je pourrais transformer cela en un modèle (en utilisant C ++ 98) sans perdre la capacité de chaîner les sorties (comme dans mon deuxième exemple), ou avoir à créer un désordre compliqué à gérer n'importe quel nombre de paramètres et types de paramètres.
DevSolar
@DevSolar: ne ferait pas inline template<class T> std::string SSTR( T x ) { return dynamic_cast< std::ostringstream & >( (std::ostringstream() << std::dec << x) ).str() }? (Je n'ai pas testé, mais je me demande ce qui ne va pas et pourquoi?
rubenvb
@rubenvb: Cela ferait l'affaire pour un individu int(mon premier exemple). Mais sans le ostreamvisible au compilateur main(comme il est caché dans la fonction de modèle), il va essayer de chercher operator<<()pour const char []mon deuxième exemple - qui croasser. Je sais que l'OP n'a demandé qu'un int, mais cette macro plus générique est si utile (et en fait assez répandue) que j'ai pensé l'inclure ici.
DevSolar
Pour la polyvalence, je préfère une fonction de modèle. Pour la guirlande peut-être qui peut être manipulée dans la même fonction avec un peu de RTTI ...
neuro
2

Vous pouvez utiliser cette fonction pour convertir intaprès std::stringavoir inclus <sstream>:

#include <sstream>

string IntToString (int a)
{
    stringstream temp;
    temp<<a;
    return temp.str();
}
dodo
la source
-2
#include <string>
#include <stdlib.h>

Voici un autre moyen simple de convertir un int en chaîne

int n = random(65,90);
std::string str1=(__String::createWithFormat("%c",n)->getCString());

vous pouvez visiter ce lien pour plus de méthodes https://www.geeksforgeeks.org/what-is-the-best-way-in-c-to-convert-a-number-to-a-string/

Vipul Dungranee
la source
doit inclure ce qui suit pour utiliser cette méthode. Fichiers d'en-tête #include <string> #include <stdlib.h>
Vipul Dungranee
-3

Supposons que je l'ai integer = 0123456789101112. Désormais, cet entier peut être converti en chaîne par la stringstreamclasse.

Voici le code en 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;

    }
Shawon
la source
n'étaient pas des réponses similaires mais plus complètes déjà données il y a plusieurs années?
Walter
Ouais, mais cette réponse est parfaite, je pense que je n'ai pas eu de réponse efficace de la part précédente.
Shawon