web-dev-qa-db-fra.com

c ++ analyse int de chaîne

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!

74
kralco626
  • 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 .

88
Nawaz

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

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

9
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;
7
Sanjit Saluja

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

4
AshleysBrain