Question

    

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

         

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 survient. .

Était-ce utile?

La solution

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

#include <string>

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

Si vous utilisez une version antérieure à C ++ 11, vous pouvez utiliser les flux C ++:

#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 /

Autres conseils

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

Archéologie

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

La voie C

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

Malgré le fait que certaines fonctions ne sont pas dans la norme, comme mentionné à 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 méthode C ++.

Utilisez les flux C ++ (dans le cas présent, 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 (le moyen 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. .

  • Le moyen le plus sûr (c'est-à-dire le C ++), si vous savez que cette partie du code n'est pas critique, il est donc préférable de s'assurer que cette partie du code ne se cassera pas au hasard, car quelqu'un aurait confondu sa taille. ou un pointeur (ce qui se passe dans la vie réelle, comme ... hier, sur mon ordinateur, car quelqu'un a pensé que c'était & "cool &" d'utiliser le moyen le plus rapide sans en avoir vraiment besoin).

Essayez sprintf ():

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

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

De plus, 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.) :

snprintf(str, sizeof(str), "%d", num);

Dans les coulisses, lexical_cast fait ceci:

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

Si vous ne voulez pas & "glisser dans &"; stimuler pour cela, puis en utilisant ce qui précède est une bonne solution.

Nous pouvons définir notre propre iota fonction dans c ++ en tant que:

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

& # 1057; ++ 11 résout finalement cette question en fournissant std::to_string . De plus, boost::lexical_cast est un outil pratique pour les anciens compilateurs.

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

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 seul entier

Vous pouvez réellement 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;
}

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

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. La raison pour laquelle vous n’utilisez pas c ++ string_format () ... ou sprintf est qu’ils sont trop lents, non?

Notez que toutes les stringstream méthodes peuvent impliquer un verrouillage sur l'utilisation de l'objet de paramètres régionaux pour le formatage. Ce peut être quelque chose à craindre si vous utilisez cette conversion à partir de plusieurs threads ...

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

int number = 123;

stringstream = s;

s << number;

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

Si vous êtes intéressé par la méthode de conversion d’entiers à chaînes rapide et sécurisée et que vous n'êtes pas limité à la bibliothèque standard, je peux recommander la méthode FormatInt à partir de la Bibliothèque au 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 benchmarks de conversion d'entier en chaîne de Boost Karma, cette méthode est plusieurs fois plus rapide que les méthodes sprintf ou std::stringstream de la glibc. Il est même plus rapide que le propre de Boost Karma int_generator comme le confirme test de performance indépendant .

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

J'ai écrit cette fonction thread-safe il y a quelque temps. Je suis très satisfait des résultats et pense que l'algorithme est léger et mince, avec des performances équivalant à 3 fois la fonction MSVC _itoa () standard. .

Voici le lien. fonction Optimale Base-10 uniquement itoa ()? Performances égales au minimum à 10X 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));

Certaines suggestions stupides sur l'utilisation de la mémoire de l'appelant 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 pense que ce code est suffisamment maigre pour être utilisé dans un environnement embarqué. YMMV, bien sûr.

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

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

Examinez l'utilisation de std :: stringstream .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top