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

cette question a déjà une réponse ici:

  • la façon la plus facile de convertir int en chaîne de caractères en C++ 25 réponses

je me demandais s'il y avait une alternative à itoa() pour convertir un entier en chaîne parce que quand je l'exécute dans visual Studio je reçois des avertissements, et quand je essayer de construire mon programme sous Linux, je reçois une erreur de compilation.

135
demandé sur Tshepang 2008-10-23 04:17:55

19 réponses

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

#include <string>

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

si vous travaillez avec avant C++11, Vous pouvez utiliser c++ streams:

#include <sstream>

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

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

167
répondu spoulson 2013-05-07 20:43:58

boost::lexical_cast fonctionne assez bien.

#include <boost/lexical_cast.hpp>
int main(int argc, char** argv) {
    std::string foo = boost::lexical_cast<std::string>(argc);
}
54
répondu Leon Timmermans 2008-10-23 00:19:56

Archéologie

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

Comme En C

utiliser sprintf. Ou snprintf. Ou n'importe quel outil que tu trouves.

Malgré le fait que certaines fonctions ne sont pas dans le standard, comme mentionné à juste titre par "onebyone" dans un de ses commentaires, la plupart des compilateurs vous offrira une alternative (par exemple Visual C++ a son propre _snprintf vous pouvez taper à snprintf si vous en avez besoin).

Le C++.

utilise les flux C++ (dans le cas présent std::stringstream (ou même Le STD déprécié::strstream, comme proposé par Herb Sutter dans un de ses livres, parce que c'est un peu plus rapide).

Conclusion

vous êtes en C++, ce qui signifie que vous pouvez choisir la façon dont vous le voulez:

  • la voie la plus rapide (i.e. la Voie C), mais vous devez être sûr que le code est un goulot d'étranglement dans votre application (les optimisations prématurées sont mauvaises, etc.) et que votre code est encapsulé en toute sécurité pour éviter les risques de dépassement de tampon.

  • la façon la plus sûre( i.e., la façon C++), si vous savez que cette partie du code n'est pas critique, donc mieux vaut être sûr que cette partie du code ne se casse pas au hasard des moments parce que quelqu'un s'est trompé de taille ou de pointeur (ce qui se produit dans la vraie vie, comme... hier, sur mon ordinateur, parce que quelqu'un a trouvé "cool" d'utiliser la voie rapide sans vraiment en avoir besoin).

46
répondu paercebal 2008-10-23 07:17:35

Essayez de sprintf():

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

sprintf() est comme printf () mais affiche une chaîne de caractères.

aussi, comme Parappa mentionné dans les commentaires, vous pourriez vouloir utiliser snprintf() pour empêcher un débordement de tampon de se produire (où le nombre que vous convertissez ne correspond pas à la taille de votre chaîne.) Cela fonctionne comme ceci:

snprintf(str, sizeof(str), "%d", num);
34
répondu Jeremy Ruten 2008-10-23 00:42:54

dans les coulisses, lexical_cast fait ceci:

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

si vous ne voulez pas" glisser dans " boost pour cela, alors l'utilisation de ce qui précède est une bonne solution.

20
répondu 1800 INFORMATION 2008-10-23 00:32:32

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

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 #include <string> .

10
répondu Tag318 2012-11-02 21:58:47

С++11 résout finalement ce std::to_string . Aussi boost::lexical_cast est un outil pratique pour les compilateurs plus âgés.

9
répondu Vasaka 2016-04-26 15:41:47

Voici une version C de itoa, avec quelques conditions:

char* custom_itoa(int i)
{
    static char output[24];  // 64-bit MAX_INT is 20 digits
    char* p = &output[23];

    for(*p--=0;i;i/=10) *p--=i%10+0x30; 
    return ++p;    
}
  • ceci ne gère pas les nombres négatifs
  • ceci ne traite pas actuellement les nombres supérieurs à 23 caractères sous forme décimale.
  • il n'est pas thread-safe
  • la valeur de retour sera effacée/corrompue dès que la fonction sera appelée de nouveau.

    donc si vous voulez garder la valeur de retour autour, vous devez strcpy il à un tampon séparé.
9
répondu abelenky 2016-09-01 13:09:40

j'utilise ces gabarits

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
répondu jm1234567890 2011-08-28 18:46:25

Essayer Coup De Pouce.Format ou FastFormat , deux bibliothèques C++ de haute qualité:

int i = 10;
std::string result;

Avec Boost.Format

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

or FastFormat

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

évidemment, ils font tous les deux beaucoup plus qu'une simple conversion d'un entier simple

6
répondu dcw 2009-05-22 21:28:36

vous pouvez convertir n'importe quoi en chaîne avec une fonction de modèle habilement é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 string, operator+, est utilisé pour concaténer une racine avec un suffixe pour générer des noms de répertoires. Le suffixe est créé en convertissant la variable de contrôle de boucle, i, en une chaîne C++, en utilisant 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
répondu Mark Renslow 2010-05-04 20:12:30

attribuer une chaîne de caractères d'une longueur suffisante, puis utiliser snprintf.

3
répondu Iain 2008-10-23 00:22:43

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 nombreux libs.

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

c'est aussi rapide comme l'éclair 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
répondu Erik Aronesty 2014-07-07 20:42:34

noter que toutes les méthodes stringstream 151920920" may impliquent un verrouillage autour de l'utilisation de l'objet local pour le formatage. Ce peut être quelque chose à se méfier de si vous utilisez cette conversion à partir de plusieurs threads...

Voir ici pour plus d'. convertissez un nombre en chaîne de longueur spécifiée en C++

1
répondu Len Holgate 2017-05-23 12:02:48
int number = 123;

stringstream = s;

s << number;

cout << ss.str() << endl;
1
répondu Kendra 2011-06-27 22:31:26

si vous êtes intéressé par la méthode de conversion rapide aussi bien que sûre integer to string et pas limité à la bibliothèque standard, je peux recommander la méthode FormatInt de la C++ Format bibliothèque:

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 références de conversion de Boost Karma, cette méthode plusieurs fois plus rapide que sprintf ou std::stringstream de glibc . C'est encore plus rapide que Boost Karma. int_generator comme l'a confirmé un benchmark indépendant .

Avertissement: je suis l'auteur de cette bibliothèque.

1
répondu vitaut 2014-04-29 17:32:54

j'ai écrit cette fonction thread-safe il y a quelque temps, et je suis très heureux des résultats et je pense que l'algorithme est léger et maigre, avec une performance qui est environ 3X la fonction MSVC_ITOA() standard.

voici le lien. base optimale-10 seulement fonction itoa ()? La Performance est au moins 10 fois supérieure à celle de sprintf(). L'indice de référence est également le test D'assurance de la 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 y a quelques suggestions stupides faites au sujet de l'utilisation du stockage de l'appelant qui laisseraient le résultat flottant quelque part dans un tampon dans l'espace d'adresse de l'appelant. Les ignorer. Le code que j'ai énuméré fonctionne parfaitement, comme le montre le code de benchmark/QA.

je crois que ce code est assez léger pour être utilisé dans un environnement embarqué. YMMV, bien sûr.

1
répondu Community 2017-05-23 12:02:48

sur les plateformes dérivées de Windows CE, il n'y a pas de iostream par défaut. La façon d'y aller est preferaby avec la famille _itoa<> , habituellement _itow<> (puisque la plupart des trucs de string sont Unicode là de toute façon).

0
répondu Johann Gerell 2008-10-23 17:34:52

la plupart des suggestions ci-dessus ne sont pas techniquement C++, ce sont des solutions C.

regarder dans l'utilisation de std:: stringstream .

-1
répondu OJ. 2008-10-23 00:31:59