Quelle est la façon la plus simple de convertir int
en équivalent string
en C ++. Je connais deux méthodes. Existe-t-il un moyen plus simple?
(1)
int a = 10;
char *intStr = itoa(a);
string str = string(intStr);
(2)
int a = 10;
stringstream ss;
ss << a;
string str = ss.str();
c++
string
int
type-conversion
Nemo
la source
la source
itoa()
prend trois paramètres.Réponses:
C ++ 11 introduit
std::stoi
(et variantes pour chaque type numérique) etstd::to_string
, les homologues du Catoi
etitoa
mais exprimés en terme destd::string
.est donc le moyen le plus court auquel je peux penser. Vous pouvez même omettre de nommer le type à l'aide du
auto
mot clé:Remarque: voir [string.conversions] ( 21,5 dans n3242 )
la source
to_string
pas membre dustd
correctif: stackoverflow.com/questions/12975341/…g++ -std=c++11 someFile.cc
std
tous les compilateurs que je connais, sauf un.Error : No instance of overloaded function "std::to_string" matches the argument list
j'obtiens cette erreur: j'utilise VS2010 c ++string s = to_string((_ULonglong)i);
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 à l'origine basée sur les macros (conservée ci-dessous) sans passer par la laideur des macros.
Usage:
Réponse originale:
Puisque la "conversion ... en chaîne" est un problème récurrent, je définis toujours la macro SSTR () dans un en-tête central de mes sources C ++:
L'utilisation est aussi simple que possible:
Ce qui précède est compatible C ++ 98 (si vous ne pouvez pas utiliser C ++ 11
std::to_string
), et n'a pas besoin d'inclusions tierces (si vous ne pouvez pas utiliser Boostlexical_cast<>
); ces deux autres solutions ont cependant de meilleures performances.la source
dynamic_cast
mais j'utilise clang pour compiler donc il s'en plaint. Si j'omis juste ledynamic_cast
alors il compile très bien; à quoi sert ledynamic_cast
cas dans ce cas? Nous créons déjà unostringstream
, alors pourquoi le lancer?ostringstream
, nous l'avons appeléoperator<<()
, qui revientostream &
- pour lequel.str()
n'est pas défini. Je me demande vraiment comment clang ferait ce travail sans le casting (ou pourquoi cela génère une erreur avec lui). Cette construction est publiée dans de nombreux endroits, et je l'utilise depuis plus d'une décennie sur de nombreux compilateurs différents, y compris MSVC, GCC et XLC, donc je suis plutôt surpris que Clang rechigne.do { } while( 0 )
n'ajouterait rien. Avec 2. et 3. vous avez probablement obtenu un point - cela pourrait être fait avec une distribution statique, et peut-être que l'un de vous assistants de modèles pourrait proposer une interface "plus agréable". Mais comme je l'ai dit, ce n'est en aucun cas une invention de moi-même. Regardez autour de vous, cette macro (macro!) Est assez omniprésente. C'est un cas de POLA en soi. Je pourrais jouer avec un peu pour le rendre plus "rationalisé".J'utilise généralement la méthode suivante:
Il est décrit en détail ici .
la source
ss
, vous en avez besoinss.clear()
. J'ai vu des résultats inattendus sans cette initialisation.clear()
unostringstream
objet nouvellement créé .clear()
réinitialise les drapeaux error / eof et aucune condition error / eof n'a encore été générée.NumberToString(23213.123)
produit23213.1
tout enstd::to_string(23213.123)
produisant23213.123000
Que se passe-t-il?Le moyen le plus courant est probablement le plus simple de votre deuxième choix dans un modèle nommé
lexical_cast
, tel que celui de Boost , donc votre code ressemble à ceci:Une des particularités de ceci est qu'il prend également en charge d'autres modèles (par exemple, dans le sens opposé, il fonctionne tout aussi bien).
Notez également que bien que Boost lexical_cast ait commencé comme une simple écriture dans un flux de chaînes, puis une extraction en retour du flux, il a maintenant quelques ajouts. Tout d'abord, des spécialisations pour un certain nombre de types ont été ajoutées, donc pour de nombreux types courants, c'est beaucoup plus rapide que d'utiliser un stringstream. Deuxièmement, il vérifie maintenant le résultat, donc (par exemple) si vous convertissez d'une chaîne en un
int
, il peut lever une exception si la chaîne contient quelque chose qui n'a pas pu être converti en unint
(par exemple,1234
réussirait, mais123abc
lancerait) .Depuis C ++ 11, il existe une
std::to_string
fonction surchargée pour les types entiers, vous pouvez donc utiliser du code comme:La norme les définit comme équivalant à effectuer la conversion avec
sprintf
(en utilisant le spécificateur de conversion qui correspond au type d'objet fourni, comme%d
pourint
), dans un tampon de taille suffisante, puis en créant unstd::string
du contenu de ce tampon.la source
Si vous avez installé Boost (ce que vous devriez):
la source
Il serait plus facile d'utiliser des chaînes de caractères:
Ou créez une fonction:
la source
Pas que je sache, en C ++ pur. Mais une petite modification de ce que vous avez mentionné
devrait fonctionner, et c'est assez court.
la source
itoa()
n'est pas une fonction standard!Vous pouvez utiliser
std::to_string
disponible en C ++ 11 comme suggéré par Matthieu M .:Ou, si les performances sont critiques (par exemple, si vous effectuez de nombreuses conversions), vous pouvez utiliser
fmt::format_int
la bibliothèque {fmt} pour convertir un entier enstd::string
:Ou une chaîne C:
Ce dernier ne fait aucune allocation de mémoire dynamique et est plus de 10 fois plus rapide que
std::to_string
sur les benchmarks Boost Karma. Voir Conversion rapide d'entier en chaîne en C ++ pour plus de détails.Notez que les deux sont thread-safe.
Contrairement à
std::to_string
,fmt::format_int
ne nécessite pas C ++ 11 et fonctionne avec n'importe quel compilateur C ++.Avertissement: je suis l'auteur de la bibliothèque {fmt}.
la source
c_str()
retourne un pointeur vers un tampon déclaré dans lafmt::FormatInt
classe - donc le pointeur retourné sera invalide à le point-virgule - voir aussi stackoverflow.com/questions/4214153/lifetime-of-temporariesstd::string::c_str()
(donc la dénomination). Si vous souhaitez l'utiliser en dehors de l'expression complète, construisez un objet.FormatInt f(42);
Vous pouvez alors l'utiliserf.c_str()
sans risque de le détruire.sprintf()
est assez 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 en 1.la source
NULL
taille et zéro pour obtenir la taille de tampon nécessaire.snprintf
(notez le préfixe SNP ) etsprintf
(notez le préfixe SP ). Vous passez la taille à la première, et il prend soin de ne pas déborder, cependant cette dernière ne connaît pas la taille du tampon et peut donc déborder.snprintf
variante en premier et unesprintf
variante ensuite. Comme la taille de la mémoire tampon est alors connue, l'appelsprintf
devient entièrement sûr.Incluez d'abord:
Ajoutez ensuite la méthode:
Utilisez la méthode comme ceci:
ou
la source
L'utilisation de stringstream pour la conversion de nombres est dangereuse!
Voir http://www.cplusplus.com/reference/ostream/ostream/operator%3C%3C/ où il indique que
operator<<
insère la sortie formatée.Selon vos paramètres régionaux actuels, un entier supérieur à 3 chiffres peut être converti en une chaîne de 4 chiffres, en ajoutant un séparateur de milliers supplémentaire.
Par exemple,
int = 1000
pourrait être converti en chaîne1.001
. Cela pourrait empêcher les opérations de comparaison de fonctionner.Je recommande donc fortement d'utiliser le
std::to_string
chemin. C'est plus facile et fait ce que vous attendez.Mise à jour (voir commentaires ci-dessous) :
la source
std::to_string
utilise également les paramètres régionaux actuels (voir en.cppreference.com/w/cpp/string/basic_string/to_string , la section «Notes»). Presque tous les outils standard (des chaînes de caractères àsprintf
, mais aussisscanf
etc.) utilisent les paramètres régionaux actuels. Je n'étais pas au courant de cela jusqu'à récemment quand cela m'a frappé durement. Utilisant actuellement des trucs locaux, pas difficile à faire.Pour C ++ 98 , il existe quelques options:
boost/lexical_cast
Boost ne fait pas partie de la bibliothèque C ++, mais contient de nombreuses extensions de bibliothèque utiles.
Quant à l'exécution, l'
lexical_cast
opération 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 redondante.itoa
Cela signifie que
gcc
/g++
ne peut pas compiler de code à l'aide deitoa
.Aucun temps d'exécution à signaler. Je n'ai pas Visual Studio installé, qui est censé être capable de compiler
itoa
.sprintf
sprintf
est une fonction de bibliothèque standard C qui fonctionne sur les chaînes C, et est une alternative parfaitement valide.L'en-
stdio.h
tête peut ne pas être nécessaire. Quant à l'exécution, l'sprintf
opération 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 le principal moyen de la bibliothèque C ++ de convertir des entiers en chaînes, et vice versa. Il existe des fonctions sœurs similaires
stringstream
qui limitent davantage l'utilisation prévue du flux, telles queostringstream
. L'utilisationostringstream
indique spécifiquement au lecteur de votre code que vous avez uniquement l'intention d'utiliser l'<<
opérateur, essentiellement. 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.Quant à l'exécution, l'
ostringstream
opération prend environ 71 microsecondes (sur ma machine), puis accélère considérablement par la suite si elle est 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.
la source
C ++ 17 fournit std :: to_chars comme une alternative indépendante des paramètres régionaux plus performante.
la source
Il est assez facile d'ajouter du sucre syntaxique qui permet de composer des chaînes à la volée d'une manière semblable à un flux
Vous pouvez maintenant ajouter ce que vous voulez (à condition qu'un opérateur
<< (std::ostream& ..)
soit défini pour lui)strmake()
et l'utiliser à la place d'unstd::string
.Exemple:
la source
ÉDITÉ. Si vous avez besoin d' une conversion rapide d'un entier avec un nombre fixe de chiffres en char * rempli à gauche avec '0' , voici l'exemple pour les architectures peu endiennes (toutes x86, x86_64 et autres):
Si vous convertissez un nombre à deux chiffres:
Si vous convertissez un nombre à trois chiffres:
Si vous convertissez un nombre à quatre chiffres:
Et ainsi de suite jusqu'à sept chiffres. Dans cet exemple,
n
est un entier donné. Après la conversion, sa représentation sous forme de chaîne est accessible comme suit(char*)&s
:REMARQUE: Si vous en avez besoin sur l'ordre des octets big-endian, bien que je ne l'ai pas testé, mais voici un exemple: pour un nombre à trois chiffres, c'est
int32_t s = 0x00303030 | (n/100)<< 24 | (n/10%10)<<16 | (n%10)<<8;
pour des nombres à quatre chiffres (64 bits arch):int64_t s = 0x0000000030303030 | (n/1000)<<56 | (n/100%10)<<48 | (n/10%10)<<40 | (n%10)<<32;
Je pense que cela devrait fonctionner.la source
Utilisation:
la source
J'utilise:
Il fonctionne sur mes compilateurs g ++ Windows et Linux.
la source
sprintf
est une méthode bien connue pour insérer des données dans une chaîne du format requis.Vous pouvez convertir un
char *
tableau en chaîne comme indiqué sur la troisième ligne.la source
Cela a fonctionné pour moi -
Mon code:
la source
stringstream
?std::to_string()
using namespace std;
:)C ++ 11 introduit
std::to_string()
pour les types numériques:la source
Utilisation:
la source
la source
Si vous utilisez MFC , vous pouvez utiliser
CString
:la source
la source
Vous pouvez maintenant utiliser
to_string(5)
.la source
std
espace de noms n'est pas non plus quelque chose que vous devriez faire. De plus, il ne semble pas s'agir d'_MAX_INT_DIG
une macro standard, donc s'il est mal défini, ce code a le grand potentiel d'induire un comportement non défini. -1Je pense que l'utilisation
stringstream
est assez simple:la source
Vous utilisez un type d'algorithme de compteur pour convertir en chaîne. J'ai obtenu cette technique en programmant des ordinateurs Commodore 64 . Il est également bon pour la programmation de jeux.
Vous prenez l'entier et prenez chaque chiffre qui est pondéré par des puissances de 10. Supposons donc que l'entier est 950.
Si l'entier est égal ou supérieur à 100 000, soustrayez 100 000 et augmentez le compteur dans la chaîne à ["000000"];
continuez ainsi jusqu'à ce qu'il n'y ait plus de numéros en position 100 000. Lâchez une autre puissance de dix.
Si l'entier est égal ou supérieur à 10 000, soustrayez 10 000 et augmentez le compteur dans la chaîne à ["000000"] + 1 position;
Continuez à le faire jusqu'à ce qu'il n'y ait plus de numéros en position 10 000.
Lâchez une autre puissance de dix
Je sais que 950 est trop petit pour être utilisé comme exemple, mais j'espère que vous avez compris.
la source