web-dev-qa-db-fra.com

Meilleure façon de convertir int en chaîne en C++

Quel est le moyen le plus simple de convertir de int en équivalent string en C++? Je suis au courant de deux méthodes. Y a-t-il un moyen plus facile?

(1)

int a = 10;
char *intStr = itoa(a);
string str = string(intStr);

(2)

int a = 10;
stringstream ss;
ss << a;
string str = ss.str();
1332
Nemo

C++ 11 introduit std::stoi (et des variantes pour chaque type numérique) et std::to_string , équivalents de C atoi et itoa mais exprimés en std::string.

#include <string> 

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

est donc le moyen le plus court auquel je puisse penser. Vous pouvez même omettre de nommer le type en utilisant le mot clé auto:

auto s = std::to_string(42);

Remarque: voir [conversions.chaîne] (21.5 dans n3242 )

1782
Matthieu M.

Reprenant une discussion avec @ v.oddou quelques années plus tard, C++ 17 a finalement fourni un moyen de faire la solution de type agnostique basée sur les macros (conservée ci-dessous) sans passer par la laideur des macros.

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

Usage:

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 ) );

Réponse originale:

"Convertir ... en chaîne" étant un problème récurrent, je définis toujours la macro SSTR () dans un en-tête central de mes sources C++:

#include <sstream>

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

L'utilisation est aussi simple que possible:

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 ) );

Ce qui précède est compatible avec C++ 98 (si vous ne pouvez pas utiliser C++ 11 std::to_string), et n’a pas besoin de tiers inclus (si vous ne pouvez pas utiliser Boost lexical_cast<>); ces deux autres solutions ont cependant une meilleure performance.

179
DevSolar

J'utilise habituellement la méthode suivante:

#include <sstream>

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

décrit en détail ici .

102
Rasoul

Le moyen le plus simple et probablement le plus courant englobe essentiellement votre deuxième choix dans un modèle nommé lexical_cast, tel que celui dans Boost , afin que votre code ressemble à ceci:

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

Une particularité de cela est qu’il prend également en charge les autres distributions (par exemple, dans la direction opposée, cela fonctionne tout aussi bien).

Notez également que bien que Boost lexical_cast ait commencé par n’écrire que dans un stringstream, puis qu’il soit extrait du flux, il contient maintenant quelques ajouts. Tout d’abord, des spécialisations pour un certain nombre de types ont été ajoutées, ce qui est nettement plus rapide que pour un type courant. Deuxièmement, il vérifie maintenant le résultat. Ainsi, par exemple, si vous convertissez une chaîne en une variable int, elle peut générer une exception si la chaîne contient quelque chose qui n'a pas pu être converti en une variable int (par exemple, 1234 réussirait, mais 123abc jetterait).

Depuis C++ 11, une fonction std::to_string est surchargée pour les types entiers, vous pouvez donc utiliser un code comme:

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

La norme les définit comme équivalant à effectuer la conversion avec sprintf (à l'aide du spécificateur de conversion correspondant au type d'objet fourni, tel que %d pour int), dans un tampon de taille suffisante, puis en créant un std::string du contenu de ce tampon. .

85
Jerry Coffin

Si vous avez installé Boost (ce que vous devriez):

#include <boost/lexical_cast.hpp>

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

Ne serait-il pas plus facile d’utiliser des courants à la chaîne?

#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

Ou faire une fonction:

#include <sstream>

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

Pas que je sache, en C++ pur. Mais une petite modification de ce que vous avez mentionné

string s = string(itoa(a));

devrait fonctionner, et c'est assez court.

19
Mehrdad

sprintf() est très bon pour la conversion de format. Vous pouvez ensuite affecter la chaîne C résultante à la chaîne C++ comme vous l'avez fait dans 1.

16
Throwback1986

Tout d'abord inclure:

#include <string>
#include <sstream>

Deuxième ajouter la méthode:

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

Utilisez la méthode comme ceci:

NumberToString(69);

ou

int x = 69;
string vStr = NumberToString(x) + " Hello Word!."
12
Alex

Vous pouvez utiliser std::to_string disponible en C++ 11 comme suggéré par Matthieu M. :

std::to_string(42);

Ou, si les performances sont critiques (par exemple, si vous effectuez de nombreuses conversions), vous pouvez utiliser fmt::FormatInt à partir de C++ Format library pour convertir un entier en std::string:

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

Ou une corde en C:

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

Ce dernier ne fait aucune allocation de mémoire dynamique et est plus de 10 fois plus rapide que std::to_string sur les tests de performance Boost Karma. Voir Conversion de entier entier en chaîne en C++ pour plus de détails.

Contrairement à std::to_string, fmt::FormatInt ne nécessite pas C++ 11 et fonctionne avec n’importe quel compilateur C++.

Disclaimer: Je suis l'auteur de la bibliothèque de formats C++.

10
vitaut

Utiliser stringstream pour la conversion de numéro est dangereux!

Voir http://www.cplusplus.com/reference/ostream/ostream/operator%3C%3C/ où il indique que operator<< insère une sortie formatée.

Selon vos paramètres régionaux actuels, un entier supérieur à 3 chiffres peut être converti en chaîne de 4 chiffres, en ajoutant un séparateur supplémentaire de milliers.

Par exemple, int = 1000 pourrait être converti en une chaîne 1.001. Cela pourrait empêcher les opérations de comparaison de fonctionner.

Je recommande donc fortement d’utiliser la méthode std::to_string. C'est plus facile et fait ce que vous attendez.

8
YesThatIsMyName

Pour C++ 98, il y a quelques options:

boost/lexical_cast

Boost ne fait pas partie de la bibliothèque C++, mais contient de nombreuses extensions de bibliothèque utiles.

Le modèle de fonction lexical_cast offre un formulaire cohérent et pratique pour prendre en charge les conversions courantes vers et à partir de types arbitraires lorsqu'ils sont représentés sous forme de texte. 
- Documentation Boost

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

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

En ce qui concerne l'exécution, l'opération lexical_cast prend environ 80 microsecondes (sur ma machine) lors de la première conversion, puis accélère considérablement par la suite si elle est effectuée de manière redondante.


itoa

Cette fonction n'est pas définie dans ANSI-C et ne fait pas partie de C++, mais est prise en charge par certains compilateurs. 
- cplusplus.com

Cela signifie que gccg++ ne peut pas compiler du code avec 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;
}

Pas d'exécution à signaler. Je n'ai pas Visual Studio installé, ce qui est apparemment capable de compiler itoa.


sprintf

sprintf est une fonction de bibliothèque standard C qui fonctionne sur les chaînes C et constitue une alternative parfaitement valide.

Compose une chaîne avec le même texte que celui qui serait imprimé si le format était utilisé sur printf, mais au lieu d'être imprimé, le contenu est stocké sous la forme d'une chaîne C dans le tampon pointé par 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;
}

L'en-tête stdio.h n'est peut-être pas nécessaire. En ce qui concerne l'exécution, l'opération sprintf prend environ 40 microsecondes (sur ma machine) lors de la première conversion, puis accélère considérablement par la suite si elle est effectuée de manière redondante.


stringstream

C’est la méthode principale utilisée par la bibliothèque C++ pour convertir les entiers en chaînes, et inversement. Il existe des fonctions soeurs similaires à stringstream qui limitent davantage l'utilisation prévue du flux, telles que ostringstream. L'utilisation de ostringstream indique spécifiquement au lecteur de votre code que vous avez seulement l'intention d'utiliser essentiellement l'opérateur <<. Cette fonction est tout ce qui est particulièrement nécessaire pour convertir un entier en chaîne. Voir cette question pour une discussion plus élaborée.

#include <sstream>
#include <string>

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

En ce qui concerne l'exécution, l'opération ostringstream prend environ 71 microsecondes (sur ma machine), puis accélère considérablement par la suite si elle est effectuée de manière redondante, mais pas autant que les fonctions précédentes.


Bien sûr, il existe d'autres options, et vous pouvez même en intégrer une dans votre propre fonction, mais cela offre un aperçu analytique de certaines des plus populaires.

8
Josh Detwiler

Il est plutôt facile d'ajouter du sucre syntaxique qui permet de composer des chaînes à la volée de manière fluide

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

Maintenant, vous pouvez ajouter ce que vous voulez (à condition qu'un opérateur << (std::ostream& ..) soit défini pour ce dernier) à strmake() et l'utiliser à la place d'un std::string.

Exemple:

#include <iostream>

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

Utilisation:

#define convertToString(x) #x

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

C++ 17 fournit std :: to_chars comme une alternative plus performante et indépendante des paramètres régionaux.

2
user10133158

J'utilise:

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();

Cela fonctionne sur mes compilateurs windows et linux g ++. 

1
J_C

Cela a fonctionné pour moi ceci Mon code:

#include <iostream>
using namespace std;

int main()
{
    int n=32;
    string s=to_string(n);
    cout << "string: " + s  << endl;
    return 0;
}
1
Gonçalo Garrido
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));
    }
}

vous pouvez maintenant utiliser to_string(5)

1
user1363411
#include "stdafx.h"
#include<iostream>
#include<string>
#include<string.h>


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
Tayyab Mazhar

Voici un autre moyen facile de faire 

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

sprintf est bien connu pour insérer des données dans une chaîne du format requis.

Vous pouvez convertir char * array en chaîne comme indiqué à la troisième ligne.

1
Natesh bhat
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
Abdullah Abdelmonem
char * bufSecs = new char[32];
char * bufMs = new char[32];
sprintf(bufSecs,"%d",timeStart.elapsed()/1000);
sprintf(bufMs,"%d",timeStart.elapsed()%1000);
0
user2047065

Pourquoi ne peux-tu pas faire

int a = 10;
string str = a + '0';
0
Ver Nick

Utiliser CString:

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

Je pense que l'utilisation de stringstream est assez facile.

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

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

Utilisation de C++ "pur" (pas de C++ 11, etc.):

#include <bits/stdc++.h>

using namespace std;

string to_str(int x) {
    ostringstream ss;
    ss << x;
    return ss.str();
}

int main()
{
    int number = 10;
    string s = to_str(number);
    cout << s << endl;
    return 0;
}
0
Nelio Alves