web-dev-qa-db-fra.com

Alternative à itoa () pour convertir un entier en chaîne C ++?

Je me demandais s'il existait une alternative à itoa() pour convertir un entier en chaîne, car lorsque je l'exécute dans Visual Studio, je reçois des avertissements et lorsque j'essaie de construire mon programme sous Linux, une erreur de compilation se produit.

140
Tomek

En C++ 11, vous pouvez utiliser std::to_string :

_#include <string>

std::string s = std::to_string(5);
_

Si vous travaillez avec des versions antérieures à C++ 11, vous pouvez utiliser les flux C++:

_#include <sstream>

int i = 5;
std::string s;
std::stringstream out;
out << i;
s = out.str();
_

Extrait de http://notfaq.wordpress.com/2006/08/30/c-convert-int-to-string/

172
spoulson

boost :: lexical_cast fonctionne plutôt bien.

#include <boost/lexical_cast.hpp>
int main(int argc, char** argv) {
    std::string foo = boost::lexical_cast<std::string>(argc);
}
54
Leon Timmermans

Archéologie

itoa était une fonction d'assistance non standard conçue pour compléter la fonction standard atoi, et cachant probablement un sprintf (la plupart de ses fonctionnalités peuvent être mises en œuvre en termes de sprintf): http://www.cplusplus.com/reference/ bibliothèque/cstdlib/itoa.html

La voie C

Utilisez sprintf. Ou snprintf. Ou quel que soit l'outil que vous trouviez.

Bien que certaines fonctions ne soient pas dans la norme, comme indiqué à juste titre par "onebyone" dans l'un de ses commentaires, la plupart des compilateurs vous proposeront une alternative (par exemple, Visual C++ a son propre _snprintf que vous pouvez utiliser si vous en avez besoin).

La manière C++.

Utilisez les flux C++ (dans le cas actuel, std :: stringstream (ou même le std :: strstream obsolète, comme proposé par Herb Sutter dans l'un de ses livres, car c'est un peu plus rapide).

Conclusion

Vous êtes en C++, ce qui signifie que vous pouvez choisir ce que vous voulez:

  • Le moyen le plus rapide (c.-à-d. Le C), mais vous devez être sûr que le code constitue un goulot d'étranglement dans votre application (les optimisations prématurées sont néfastes, etc.) et que votre code est encapsulé en toute sécurité pour éviter les dépassements de mémoire tampon.

  • La méthode la plus sûre (c.-à-d. La méthode C++), si vous savez que cette partie du code n'est pas critique, vous devez donc vous assurer que cette partie du code ne se cassera pas au hasard, car quelqu'un aurait pris une taille ou un pointeur (ce qui arrive). dans la vraie vie, comme ... hier, sur mon ordinateur, parce que quelqu'un trouvait ça "cool" d'utiliser le moyen le plus rapide sans vraiment en avoir besoin).

47
paercebal

Essayez de sprintf ():

char str[12];
int num = 3;
sprintf(str, "%d", num); // str now contains "3"

sprintf () est comme printf () mais génère une chaîne.

En outre, comme Parappa l'a mentionné dans les commentaires, vous pouvez utiliser snprintf () pour empêcher un débordement de mémoire tampon (le nombre que vous convertissez ne correspond pas à la taille de votre chaîne). Il fonctionne comme suit:

snprintf(str, sizeof(str), "%d", num);
34
Jeremy Ruten

Dans les coulisses, lexical_cast fait ceci:

std::stringstream str;
str << myint;
std::string result;
str >> result;

Si vous ne voulez pas "glisser en" boost pour cela, alors utilisez ce qui précède est une bonne solution.

20
1800 INFORMATION

Nous pouvons définir notre propre fonction iota en c ++ comme suit:

string itoa(int a)
{
    string ss="";   //create empty string
    while(a)
    {
        int x=a%10;
        a/=10;
        char i='0';
        i=i+x;
        ss=i+ss;      //append new character at the front of the string!
    }
    return ss;
}

N'oubliez pas de #include <string>.

10
Tag318

С ++ 11 résout finalement ceci en fournissant std::to_string . De plus, _boost::lexical_cast_ est un outil pratique pour les anciens compilateurs.

9
Vasaka

J'utilise ces modèles

template <typename T> string toStr(T tmp)
{
    ostringstream out;
    out << tmp;
    return out.str();
}


template <typename T> T strTo(string tmp)
{
    T output;
    istringstream in(tmp);
    in >> output;
    return output;
}
8
jm1234567890

Essayez Boost.Format ou FastFormat , les deux bibliothèques C++ de haute qualité:

int i = 10;
std::string result;

Avec Boost.Format

result = str(boost::format("%1%", i));

ou FastFormat

fastformat::fmt(result, "{0}", i);
fastformat::write(result, i);

Évidemment, ils font tous deux beaucoup plus que la simple conversion d'un entier

6
dcw

Vous pouvez en fait convertir n'importe quoi en chaîne avec une fonction modèle intelligemment écrite. Cet exemple de code utilise une boucle pour créer des sous-répertoires dans un système Win-32. L'opérateur de concaténation de chaîne, opérateur +, est utilisé pour concaténer une racine avec un suffixe pour générer des noms de répertoire. Le suffixe est créé en convertissant la variable de contrôle de boucle, i, en une chaîne C++, à l'aide de la fonction template, et en la concaténant avec une autre chaîne.

//Mark Renslow, Globe University, Minnesota School of Business, Utah Career College
//C++ instructor and Network Dean of Information Technology

#include <cstdlib>
#include <iostream>
#include <string>
#include <sstream> // string stream
#include <direct.h>

using namespace std;

string intToString(int x)
{
/**************************************/
/* This function is similar to itoa() */
/* "integer to alpha", a non-standard */
/* C language function. It takes an   */
/* integer as input and as output,    */
/* returns a C++ string.              */
/* itoa()  returned a C-string (null- */
/* terminated)                        */
/* This function is not needed because*/
/* the following template function    */
/* does it all                        */
/**************************************/   
       string r;
       stringstream s;

       s << x;
       r = s.str();

       return r;

}

template <class T>
string toString( T argument)
{
/**************************************/
/* This template shows the power of   */
/* C++ templates. This function will  */
/* convert anything to a string!      */
/* Precondition:                      */
/* operator<< is defined for type T    */
/**************************************/
       string r;
       stringstream s;

       s << argument;
       r = s.str();

       return r;

}

int main( )
{
    string s;

    cout << "What directory would you like me to make?";

    cin >> s;

    try
    {
      mkdir(s.c_str());
    }
    catch (exception& e) 
    {
      cerr << e.what( ) << endl;
    }

    chdir(s.c_str());

    //Using a loop and string concatenation to make several sub-directories
    for(int i = 0; i < 10; i++)
    {
        s = "Dir_";
        s = s + toString(i);
        mkdir(s.c_str());
    }
    system("PAUSE");
    return EXIT_SUCCESS;
}
6
Mark Renslow

Allouez une chaîne de longueur suffisante, puis utilisez snprintf.

3
Iain

La meilleure réponse, IMO, est la fonction fournie ici:

http://www.jb.man.ac.uk/~slowe/cpp/itoa.html

Il imite la fonction non-ANSI fournie par de nombreuses bibliothèques.

char* itoa(int value, char* result, int base);

Il est également ultra-rapide et optimise bien sous -O3, et la raison pour laquelle vous n’utilisez pas c ++ string_format () ... ou sprintf est qu’ils sont trop lents, non?

2
Erik Aronesty

J'ai écrit cette fonction thread-safe il y a quelque temps, et je suis très heureux des résultats. 3X la fonction MSVC _itoa () standard.

Voici le lien. Fonction Optimale Base-10 uniquement itoa ()? La performance est au moins 10 fois celle de sprintf (). Le repère est également le test d’assurance qualité de la fonction, comme suit.

start = clock();
for (int i = LONG_MIN; i < LONG_MAX; i++) {
    if (i != atoi(_i32toa(buff, (int32_t)i))) {
        printf("\nError for %i", i);
    }
    if (!i) printf("\nAt zero");
}
printf("\nElapsed time was %f milliseconds", (double)clock() - (double)(start));

Il existe des suggestions stupides sur l'utilisation de la mémoire de l'appelant qui laisseraient le résultat flotter quelque part dans une mémoire tampon de l'espace adresse de l'appelant. Ignore les. Le code que j'ai énuméré fonctionne parfaitement, comme le montre le code de référence/assurance qualité.

Je crois que ce code est suffisamment maigre pour être utilisé dans un environnement embarqué. YMMV, bien sûr.

1
user1899861
int number = 123;

stringstream = s;

s << number;

cout << ss.str() << endl;
1
Kendra

Notez que toutes les méthodes stringstream peuvent impliquer un verrouillage sur l'utilisation de l'objet de paramètres régionaux pour la mise en forme. Ceci peut être une chose à éviter si vous utilisez cette conversion à partir de plusieurs threads ...

Voir ici pour plus. Convertit un nombre en chaîne avec une longueur spécifiée en C++

1
Len Holgate

Si vous êtes intéressé par la méthode de conversion entier à chaîne rapide et sécurisée et que vous n'êtes pas limité à la bibliothèque standard, je peux recommander la méthode FormatInt de la bibliothèque Format C++ :

fmt::FormatInt(42).str();   // convert to std::string
fmt::FormatInt(42).c_str(); // convert and get as a C string
                            // (mind the lifetime, same as std::string::c_str())

Selon les repères de conversion entiers en chaînes de Boost Karma, cette méthode est plusieurs fois plus rapide que sprintf ou std::stringstream de la glibc. Il est même plus rapide que le propre int_generator de Boost Karma, comme le confirme un critère indépendant .

Disclaimer: Je suis l'auteur de cette bibliothèque.

1
vitaut

Sur les plates-formes dérivées de Windows CE, il n'y a pas de iostreams par défaut. La façon de s'y rendre est préférable avec la famille _itoa<>, généralement _itow<> (puisque la plupart des chaînes sont en Unicode de toute façon).

0
Johann Gerell