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.
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 /
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);
}
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).
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);
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.
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>
.
С++11 résout finalement ce std::to_string
.
Aussi boost::lexical_cast
est un outil pratique pour les compilateurs plus âgés.
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 devezstrcpy
il à un tampon séparé.
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;
}
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
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;
}
attribuer une chaîne de caractères d'une longueur suffisante, puis utiliser 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 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?
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++
int number = 123;
stringstream = s;
s << number;
cout << ss.str() << endl;
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.
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.
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).
la plupart des suggestions ci-dessus ne sont pas techniquement C++, ce sont des solutions C.
regarder dans l'utilisation de std:: stringstream .