Le moyen le plus simple de convertir un entier en chaîne en C ++


1574

Quelle est la façon la plus simple de convertir inten équivalent stringen 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();

4
Je pense que les deux méthodes que vous avez données sont de bonnes solutions. cela dépend du contexte dans lequel vous devez le faire. Si vous travaillez déjà avec des flux, par exemple en lisant ou en écrivant un fichier, votre deuxième méthode est la meilleure. Si vous devez passer un int sous forme de chaîne à un argument de fonction, alors itoa pourrait être un moyen simple. Mais la plupart du temps, la conversion int en chaîne se produit lors du traitement des fichiers, les flux sont donc appropriés.
Charles Brunet

41
Comment l'option 1 fonctionne-t-elle même pour vous? C'est ma compréhension qui itoa()prend trois paramètres.
b1nary.atr0phy

1
itoa sera plus rapide que l'équivalent de flux. Il existe également des moyens de réutiliser le tampon de chaîne avec la méthode itoa (en évitant les allocations de tas si vous générez fréquemment des chaînes, par exemple pour une sortie numérique à mise à jour rapide). Alternativement, vous pouvez générer un streambuf personnalisé pour réduire une partie des frais généraux d'allocation, etc. La construction du flux en premier lieu n'est pas non plus une entreprise à faible coût.
Pete

6
@Pete: Une fois que vous commencez à vous inquiéter de ce qui est le plus rapide, vous voudrez regarder stackoverflow.com/questions/4351371/…
Ben Voigt

20
Notez que itoa () ne fait pas partie de la norme et donc son utilisation rend votre code non portable car tous les compilateurs ne le prennent pas en charge. Pour Linux, vous êtes certainement absent, sauf si vous utilisez autre chose que GCC, qui ne prend pas en charge cette fonction. Si vous avez C ++ 0x, allez avec ce que @Matthieu a suggéré dans sa réponse. Si ce n'est pas le cas, optez pour stringstream car c'est une fonctionnalité bien prise en charge et votre code doit être compatible avec tous les compilateurs C ++. Comme alternative, vous pouvez toujours utiliser sprintf ().
rbaleksandar

Réponses:


2102

C ++ 11 introduit std::stoi(et variantes pour chaque type numérique) et std::to_string, les homologues du C atoiet itoamais exprimés en terme de std::string.

#include <string> 

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

est donc le moyen le plus court auquel je peux penser. Vous pouvez même omettre de nommer le type à l'aide du automot clé:

auto s = std::to_string(42);

Remarque: voir [string.conversions] ( 21,5 dans n3242 )


199
to_stringpas membre du stdcorrectif: stackoverflow.com/questions/12975341/…
Ben

36
Ou en fonction de votre compilateur, il suffit de définir la bonne langue standard:g++ -std=c++11 someFile.cc
Thomas M. DuBuisson

12
@Steve: c'est censé l'être. C'est un membre de stdtous les compilateurs que je connais, sauf un.
Mooing Duck

5
@Matthiew M. J'utilise le même que celui que vous suggérez mais Error : No instance of overloaded function "std::to_string" matches the argument list j'obtiens cette erreur: j'utilise VS2010 c ++

19
@Flying: sous VS2010, vous devez explicitement convertir l'entier de conversion en l'un des types suivants [_Longlong, _ULonglong, long double]; Soit:string s = to_string((_ULonglong)i);
Zac

184

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.

// variadic template
template < typename... Args >
std::string sstr( Args &&... args )
{
    std::ostringstream sstr;
    // fold expression
    ( sstr << std::dec << ... << args );
    return sstr.str();
}

Usage:

int i = 42;
std::string s = sstr( "i is: ", i );
puts( sstr( i ).c_str() );

Foo x( 42 );
throw std::runtime_error( sstr( "Foo is '", x, "', i is ", i ) );

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 ++:

#include <sstream>

#define SSTR( x ) static_cast< std::ostringstream & >( \
        ( std::ostringstream() << std::dec << x ) ).str()

L'utilisation est aussi simple que possible:

int i = 42;
std::string s = SSTR( "i is: " << i );
puts( SSTR( i ).c_str() );

Foo x( 42 );
throw std::runtime_error( SSTR( "Foo is '" << x << "', i is " << i ) );

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 Boost lexical_cast<>); ces deux autres solutions ont cependant de meilleures performances.


2
Je ne suis pas très familier avec dynamic_castmais j'utilise clang pour compiler donc il s'en plaint. Si j'omis juste le dynamic_castalors il compile très bien; à quoi sert le dynamic_castcas dans ce cas? Nous créons déjà un ostringstream, alors pourquoi le lancer?
Mathew

2
@Mathew: Le lien dans ma réponse mène à une description détaillée de chaque partie de la construction. Pendant que nous créions un ostringstream, nous l'avons appelé operator<<(), qui revient ostream &- 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.
DevSolar

5
Je suis juste venu à la fête pour la curiosité et j'ai voté contre. Raison: trop de votes pour une solution peu élégante et probablement lente. 1. utilisation des macros. Je ne désapprouve systématiquement aucune macro, mais celle-ci est trop courte et les clients finaux craignent toujours la répétition de l'argument, en plus de la peur des macros multilignes non protégées. (non protégé par do {} while (0)) 2. dynamic_cast. il semble que vous n'ayez besoin que d'un static_cast ici, sauf si vous voulez affirmer que la bibliothèque est bien implémentée comme vous l'espérez. dans ce cas, vous devez plutôt utiliser boost :: polymorphic_downcast.
v.oddou

2
@ v.oddou: Vous êtes bien sûr libre de critiquer. Mais 1. n'est pas valide - la macro est une instruction unique, 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é".
DevSolar

1
@ v.oddou: Regardez ce que j'ai trouvé parmi les choses que C ++ 17 nous a apportées. :-) J'espère que vous aimez la réponse mise à jour.
DevSolar

109

J'utilise généralement la méthode suivante:

#include <sstream>

template <typename T>
  std::string NumberToString ( T Number )
  {
     std::ostringstream ss;
     ss << Number;
     return ss.str();
  }

Il est décrit en détail ici .


2
Avant d'utiliser ss, vous en avez besoin ss.clear(). J'ai vu des résultats inattendus sans cette initialisation.
lifebalance

14
@ lifebalance: Je n'ai jamais vu un tel comportement.
Rasoul

18
@lifebalance: Vous n'avez pas besoin d' clear()un ostringstreamobjet nouvellement créé . clear()réinitialise les drapeaux error / eof et aucune condition error / eof n'a encore été générée.
Remy Lebeau

2
@Rasoul NumberToString(23213.123)produit 23213.1tout en std::to_string(23213.123)produisant 23213.123000Que se passe-t-il?
Killzone Kid

1
@KillzoneKid Ceci est dû au fait que std 'ostream est avec état (cela signifie que tout changement d'état précédent est conservé, comme le nombre de chiffres décimaux) alors que cette méthode démarre avec un état par défaut.
xryl669

85

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:

int a = 10;
string s = lexical_cast<string>(a);

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 un int(par exemple, 1234réussirait, mais 123abclancerait) .

Depuis C ++ 11, il existe une std::to_stringfonction surchargée pour les types entiers, vous pouvez donc utiliser du code comme:

int a = 20;
std::string s = std::to_string(a);
// or: auto s = std::to_string(a);

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 %dpour int), dans un tampon de taille suffisante, puis en créant un std::stringdu contenu de ce tampon.


2
Bien, je préfère la réponse de Kevin, car il montre l'inclusion et l'espace de noms. Juste un petit reproche. :) Bon travail!
Jason R. Mick

4
Je dirais que c'est la voie à suivre si vous n'avez pas de support C ++ 11.
Alex

40

Si vous avez installé Boost (ce que vous devriez):

#include <boost/lexical_cast.hpp>

int num = 4;
std::string str = boost::lexical_cast<std::string>(num);

4
Convenu sur l'installation de boost. Je pense que plus souvent on formaterait la chaîne. Dans ce but, je préfère boost :: format, par exemple format ("% 02d", nombre) .str ()
Werner Erasmus

28

Il serait plus facile d'utiliser des chaînes de caractères:

#include <sstream>

int x = 42;          // The integer
string str;          // The string
ostringstream temp;  // 'temp' as in temporary
temp << x;
str = temp.str();    // str is 'temp' as string

Ou créez une fonction:

#include <sstream>

string IntToString(int a)
{
    ostringstream temp;
    temp << a;
    return temp.str();
}

18

Pas que je sache, en C ++ pur. Mais une petite modification de ce que vous avez mentionné

string s = string(itoa(a));

devrait fonctionner, et c'est assez court.


55
itoa()n'est pas une fonction standard!
dessinateur

4
@cartoonist: Alors qu'est-ce que c'est?
user541686

20
Cette fonction n'est pas définie dans ANSI-C et C ++. Il n'est donc pas pris en charge par certains compilateurs tels que g ++.
dessinateur

17

Vous pouvez utiliser std::to_stringdisponible en C ++ 11 comme suggéré par Matthieu M .:

std::to_string(42);

Ou, si les performances sont critiques (par exemple, si vous effectuez de nombreuses conversions), vous pouvez utiliser fmt::format_intla bibliothèque {fmt} pour convertir un entier en std::string:

fmt::format_int(42).str();

Ou une chaîne C:

fmt::format_int f(42);
f.c_str();

Ce dernier ne fait aucune allocation de mémoire dynamique et est plus de 10 fois plus rapide que std::to_stringsur 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_intne nécessite pas C ++ 11 et fonctionne avec n'importe quel compilateur C ++.

Avertissement: je suis l'auteur de la bibliothèque {fmt}.


2
J'étais curieux de ne pas avoir d'allocation de mémoire dynamique tout en restant threadsafe (rentrant), alors j'ai lu votre code - le c_str()retourne un pointeur vers un tampon déclaré dans la fmt::FormatIntclasse - donc le pointeur retourné sera invalide à le point-virgule - voir aussi stackoverflow.com/questions/4214153/lifetime-of-temporaries
Soren

1
Oui, le même comportement qu'avec std::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'utiliser f.c_str()sans risque de le détruire.
vitaut

1
J'obtiens quelque chose de bizarre lorsque j'essaie de convertir de int en chaîne en utilisant std :: to_string (num). Si je stocke le résultat dans une variable et essaie d'y accéder comme stringNum [1] ou stringNum [n] lorsque n augmente, j'obtiens des ordures.
user8951490

1
C'est définitivement la bonne réponse à cette question: un code efficace et standard qui n'est pas dynamique.
xryl669

16

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.


1
Hé, oui. Cependant, je compte généralement sur snprintf () et ses amis pour quoi que ce soit de conséquence lors de la manipulation des chaînes C.
Throwback1986

1
@MatthieuM. Votre commentaire prouve en outre que vous ne l'êtes pas. Si la sortie a été tronquée en raison de cette limite, la valeur de retour est le nombre de caractères (à l'exclusion de l'octet nul final) qui auraient été écrits dans la chaîne finale si suffisamment d'espace avait été disponible. Ainsi, une valeur de retour de taille ou plus signifie que la sortie a été tronquée. Vous l'appelez donc avec une NULLtaille et zéro pour obtenir la taille de tampon nécessaire.
user1095108

2
@ user1095108: Je pense que vous vous trompez snprintf(notez le préfixe SNP ) et sprintf(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.
Matthieu M.

1
L'idée est d'appeler une snprintfvariante en premier et une sprintfvariante ensuite. Comme la taille de la mémoire tampon est alors connue, l'appel sprintfdevient entièrement sûr.
user1095108

1
@ user1095108 Ah, oui. Si le premier tampon de snprintf est insuffisant, la valeur de retour vous indique ce qui serait suffisant. J'utiliserais toujours snprintf pour le deuxième appel, car compter sur les implémentations de sprintf et snprintf pour correspondre est inutilement dangereux.
mabraham

11

Incluez d'abord:

#include <string>
#include <sstream>

Ajoutez ensuite la méthode:

template <typename T>
string NumberToString(T pNumber)
{
 ostringstream oOStrStream;
 oOStrStream << pNumber;
 return oOStrStream.str();
}

Utilisez la méthode comme ceci:

NumberToString(69);

ou

int x = 69;
string vStr = NumberToString(x) + " Hello word!."

10

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 queoperator<< 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 = 1000pourrait ê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_stringchemin. C'est plus facile et fait ce que vous attendez.

Mise à jour (voir commentaires ci-dessous) :

C ++ 17 fournit std::to_charsune alternative indépendante des paramètres régionaux plus performante


2
Je reconnais que c'est un problème grave si vous avez besoin d'échanger des données. Malheureusement, std::to_stringutilise é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 aussi sscanfetc.) 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.
Bert Bril

Dans le lien ci-dessus, il est également statet que C ++ 17 fournit std :: to_chars comme une alternative indépendante des paramètres régionaux plus performante.
YesThatIsMyName

Malheureusement, je suis coincé avec C ++ 11 pour les prochaines années (une amélioration déjà, heureusement).
Bert Bril

1
from_chars et to_chars seraient parfaits mais malheureusement, ils ne proposaient pas de variante wchar_t.
gast128

8

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.

Le lexical_castmodèle de fonction offre une forme pratique et cohérente pour prendre en charge les conversions courantes vers et depuis des types arbitraires lorsqu'ils sont représentés sous forme de texte.
- Documentation de Boost

#include "boost/lexical_cast.hpp"
#include <string>

int main() {
    int x = 5;
    std::string x_str = boost::lexical_cast<std::string>(x);
    return 0;
}

Quant à l'exécution, l' lexical_castopé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

Cette fonction n'est pas définie dans ANSI-C et ne fait pas partie de C ++, mais est prise en charge par certains compilateurs.
- cplusplus.com

Cela signifie que gcc/ g++ne peut pas compiler de code à l'aide de itoa.

#include <stdlib.h>

int main() {
    int x = 5;
    char * x_str = new char[2];
    x_str = itoa(x, x_str, 10); // base 10
    return 0;
}

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.

Compose une chaîne avec le même texte qui serait imprimé si le format était utilisé sur printf, mais au lieu d'être imprimé, le contenu est stocké sous forme de chaîne C dans le tampon pointé par str.
- cplusplus.com

#include <stdio.h>

int main() {
    int x = 5;
    char * x_str = new char[2];
    int chars_written = sprintf(x_str, "%d", x);
    return 0;
}

L'en- stdio.htête peut ne pas être nécessaire. Quant à l'exécution, l' sprintfopé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 stringstreamqui limitent davantage l'utilisation prévue du flux, telles que ostringstream. L'utilisation ostringstreamindique 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.

#include <sstream>
#include <string>

int main() {
    int x = 5;
    std::ostringstream stream;
    stream << x;
    std::string x_str = stream.str();
    return 0;
}

Quant à l'exécution, l' ostringstreamopé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.


Merci de prendre soin de nous (utilisateurs C ++ 98)
A. B

@AB Je ne peux pas croire qu'il reste encore des utilisateurs de C ++ 98.
Kotauskas

@VladislavToncharov Lorsque votre travail consiste uniquement à prendre en charge le matériel et le code hérités, vous vous débarrassez de l'ancien en utilisant des normes de l'industrie plus récentes. Il y a un été, j'écrivais du code en Python 2.3.
Joshua Detwiler

@JoshuaDetwiler Oh, j'ai oublié ça, désolé.
Kotauskas

4

C ++ 17 fournit std :: to_chars comme une alternative indépendante des paramètres régionaux plus performante.


3

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

#include <string>
#include <sstream>

struct strmake {
    std::stringstream s;
    template <typename T> strmake& operator << (const T& x) {
        s << x; return *this;
    }   
    operator std::string() {return s.str();}
};

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:

#include <iostream>

int main() {
    std::string x =
      strmake() << "Current time is " << 5+5 << ":" << 5*5 << " GST";
    std::cout << x << std::endl;
}

2

É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:

int32_t s = 0x3030 | (n/10) | (n%10) << 8;

Si vous convertissez un nombre à trois chiffres:

int32_t s = 0x303030 | (n/100) | (n/10%10) << 8 | (n%10) << 16;

Si vous convertissez un nombre à quatre chiffres:

int64_t s = 0x30303030 | (n/1000) | (n/100%10)<<8 | (n/10%10)<<16 | (n%10)<<24;

Et ainsi de suite jusqu'à sept chiffres. Dans cet exemple, nest un entier donné. Après la conversion, sa représentation sous forme de chaîne est accessible comme suit (char*)&s:

std::cout << (char*)&s << std::endl;

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.


2
Et l'ordre des octets?
shjeff

Ce comportement non défini n'est-il pas dû à l'alias de pointeur?
dgnuff

1
@shjeff merci pour le commentaire, j'ai ajouté une note sur l'endianité à la réponse.
Alek

@dgnuff merci de l'avoir signalé, même si je n'ai eu aucun problème avec cela, vous avez raison. J'ai légèrement modifié la réponse afin qu'elle soit conforme aux règles strictes d'alias, merci.
Alek

1

Utilisation:

#define convertToString(x) #x

int main()
{
    convertToString(42); // Returns const char* equivalent of 42
}

3
Fonctionne uniquement avec des nombres littéraux, n'évalue pas le contenu variable, bien qu'utile parfois.
Wolf

Droite. Mais définitivement à portée de main
maverick9888

1
Ne fonctionne qu'à la compilation avec des constantes littérales, je pense que l'OP demande une conversion dynamique, en utilisant des entiers variables
Ing. Gerardo Sánchez

0

J'utilise:

int myint = 0;
long double myLD = 0.0;

string myint_str = static_cast<ostringstream*>(&(ostringstream() << myint))->str();
string myLD_str = static_cast<ostringstream*>(&(ostringstream() << myLD))->str();

Il fonctionne sur mes compilateurs g ++ Windows et Linux.


0

Voici un autre moyen simple de le faire

char str[100];
sprintf(str, "%d", 101);
string s = str;

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.


0

Cela a fonctionné pour moi -

Mon code:

#include <iostream>
using namespace std;

int main()
{
    int n = 32;
    string s = to_string(n);
    cout << "string: " + s  << endl;
    return 0;
}

En utilisant essentiellement quoi? stringstream?
Peter Mortensen

@PeterMortensen Regardez attentivement, c'eststd::to_string()
Kotauskas

j'ai using namespace std;:)
Gonçalo Garrido

0

C ++ 11 introduit std::to_string()pour les types numériques:

int n = 123; // Input, signed/unsigned short/int/long/long long/float/double
std::string str = std::to_string(n); // Output, std::string

4
Salut! Pourriez-vous ajouter une explication sur pourquoi et comment cela fournit une réponse à la question?
anothernode

0

Utilisation:

#include<iostream>
#include<string>

std::string intToString(int num);

int main()
{
    int integer = 4782151;

    std::string integerAsStr = intToString(integer);

    std::cout << "integer = " << integer << std::endl;
    std::cout << "integerAsStr = " << integerAsStr << std::endl;

    return 0;
}

std::string intToString(int num)
{
    std::string numAsStr;

    while (num)
    {
        char toInsert = (num % 10) + 48;
        numAsStr.insert(0, 1, toInsert);

        num /= 10;
    }
    return numAsStr;
}

1
Échoue complètement pour n≤0
Toby Speight

-1
string number_to_string(int x) {

    if (!x)
        return "0";

    string s, s2;
    while(x) {
        s.push_back(x%10 + '0');
        x /= 10;
    }
    reverse(s.begin(), s.end());
    return s;
}

1
Merci pour cet extrait de code, qui pourrait fournir une aide limitée à court terme. Une explication appropriée améliorerait considérablement sa valeur à long terme en montrant pourquoi c'est une bonne solution au problème, et la rendrait plus utile aux futurs lecteurs avec d'autres questions similaires. Veuillez modifier votre réponse pour ajouter des explications, y compris les hypothèses que vous avez faites.
Toby Speight

Échoue complètement pour n≤0
Toby Speight

Ajoutez des commentaires, expliquez votre réponse, lisez comment répondre .
Aksen P

-1

Si vous utilisez MFC , vous pouvez utiliser CString:

int a = 10;
CString strA;
strA.Format("%d", a);

8
Vous devez noter qu'il s'agit d'une extension réservée à
JonnyJD

1
J'adore l'idée de CString :: Format (). Malheureusement, il n'est pas portable MS uniquement.
Nick

1
J'ai mis à jour ma réponse pour inclure les informations provenant de votre commentaire @JonnyJD, car je continue à recevoir des
votes négatifs

-2
char * bufSecs = new char[32];
char * bufMs = new char[32];
sprintf(bufSecs, "%d", timeStart.elapsed()/1000);
sprintf(bufMs, "%d", timeStart.elapsed()%1000);

12
fuit la mémoire, -1 de moi
paulm

Cela sent le dépassement de tampon.
Kotauskas du

-2
namespace std
{
    inline string to_string(int _Val)
    {   // Convert long long to string
        char _Buf[2 * _MAX_INT_DIG];
        snprintf(_Buf, "%d", _Val);
        return (string(_Buf));
    }
}

Vous pouvez maintenant utiliser to_string(5).


10
Bien que cette solution fonctionne, elle est fortement déconseillée! Les noms commençant par un soulignement et une majuscule sont réservés au compilateur, vous ne devriez jamais les utiliser. Injecter des fonctions dans l' stdespace de noms n'est pas non plus quelque chose que vous devriez faire. De plus, il ne semble pas s'agir d' _MAX_INT_DIGune macro standard, donc s'il est mal défini, ce code a le grand potentiel d'induire un comportement non défini. -1
iFreilicht

6
Qu'est-ce que _MAX_INT_DIG et pourquoi est-il doublé?
paulm

-2

Je pense que l'utilisation stringstreamest assez simple:

 string toString(int n)
 {
     stringstream ss(n);
     ss << n;
     return ss.str();
 }

 int main()
 {
    int n;
    cin >> n;
    cout << toString(n) << endl;
    return 0;
 }

Cela a été mentionné dans la question et est malheureusement assez lent.
Kotauskas

-3

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

  • Répétez le motif

Je sais que 950 est trop petit pour être utilisé comme exemple, mais j'espère que vous avez compris.


Il n'est pas très utile de décrire un algorithme, plutôt que de montrer un exemple en code.
cdeerinck
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.