Duplicate possible:
Comment analyser une chaîne d'un int en C++?
J'ai fait des recherches et certaines personnes disent d'utiliser atio et d'autres disent que c'est mauvais, et je ne peux pas le faire fonctionner de toute façon.
Donc, je veux juste demander à plat, quelle est la bonne façon de convertir une chaîne en un int.
string s = "10";
int i = s....?
Merci!
En C++ 11, utilisez std::stoi
comme:
std::string s = "10";
int i = std::stoi(s);
Notez que std::stoi
lancera une exception de type std::invalid_argument
si la conversion est impossible, ou std::out_of_range
si la conversion entraîne un débordement (c'est-à-dire lorsque la valeur de chaîne est trop grande pour le type int
). Vous pouvez utiliser std::stol
ou std:stoll
bien que dans le cas où int
semble trop petit pour la chaîne en entrée.
En C++ 03/98, l'un des éléments suivants peut être utilisé:
std::string s = "10";
int i;
//approach one
std::istringstream(s) >> i; //i is 10 after this
//approach two
sscanf(s.c_str(), "%d", &i); //i is 10 after this
Notez que les deux approches ci-dessus échoueraient pour l'entrée s = "10jh"
. Ils renverront 10 au lieu de signaler une erreur. Ainsi, l'approche sûre et robuste consiste à écrire votre propre fonction qui analyse la chaîne d'entrée et à vérifier chaque caractère pour vérifier s'il s'agit d'un chiffre ou non, puis à travailler en conséquence. Voici une implémentation robuste (non testée cependant):
int to_int(char const *s)
{
if ( s == NULL || *s == '\0' )
throw std::invalid_argument("null or empty string argument");
bool negate = (s[0] == '-');
if ( *s == '+' || *s == '-' )
++s;
if ( *s == '\0')
throw std::invalid_argument("sign character only.");
int result = 0;
while(*s)
{
if ( *s >= '0' && *s <= '9' )
{
result = result * 10 - (*s - '0'); //assume negative number
}
else
throw std::invalid_argument("invalid input string");
++s;
}
return negate ? result : -result; //-result is positive!
}
Cette solution est une version légèrement modifiée de mon autre solution .
Vous pouvez utiliser boost :: lexical_cast :
#include <iostream>
#include <boost/lexical_cast.hpp>
int main( int argc, char* argv[] ){
std::string s1 = "10";
std::string s2 = "abc";
int i;
try {
i = boost::lexical_cast<int>( s1 );
}
catch( boost::bad_lexical_cast & e ){
std::cout << "Exception caught : " << e.what() << std::endl;
}
try {
i = boost::lexical_cast<int>( s2 );
}
catch( boost::bad_lexical_cast & e ){
std::cout << "Exception caught : " << e.what() << std::endl;
}
return 0;
}
Il n'y a pas de "bonne voie". Si vous voulez une solution universelle (mais non optimale), vous pouvez utiliser une conversion boost :: lexical.
Une solution courante pour C++ consiste à utiliser std :: ostream et << operator. Vous pouvez utiliser une méthode stringstream et stringstream :: str () pour la conversion en chaîne.
Si vous avez vraiment besoin d’un mécanisme rapide (rappelez-vous la règle 20/80), vous pouvez rechercher une solution "dédiée" comme http://www.partow.net/programming/strtk/index.html
Meilleures salutations,
Marcin
Vous pouvez utiliser istringstream .
string s = "10";
// create an input stream with your string.
istringstream is(str);
int i;
// use is like an input stream
is >> i;
Quelques fonctions rapides pratiques (si vous n'utilisez pas Boost):
template<typename T>
std::string ToString(const T& v)
{
std::ostringstream ss;
ss << v;
return ss.str();
}
template<typename T>
T FromString(const std::string& str)
{
std::istringstream ss(str);
T ret;
ss >> ret;
return ret;
}
Exemple:
int i = FromString<int>(s);
std::string str = ToString(i);
Fonctionne pour tous les types de flux (flotteurs, etc.). Vous aurez besoin de #include <sstream>
et éventuellement aussi #include <string>
.