IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SL & STL C++ Discussion :

Savoir si une string est un nombre


Sujet :

SL & STL C++

  1. #1
    Membre habitué Avatar de SteelBox
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    446
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Novembre 2002
    Messages : 446
    Points : 194
    Points
    194
    Par défaut Savoir si une string est un nombre
    Bonjour, j'ai trouvé une méthode pour savoir si une string ne contenait que des chiffres :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
       float f;
       istringstream iss(chaine);
     
       return (iss >> f) && !(iss >> chaine);
    Je vois bien à quoi sert le premier test : (iss >> f) mais le deuxième.
    Pourquoi essai t-on de remettre le flot dans chaine ? Le premier test n'est pas suffisant pour savoir si c'est un nombre ? si non, pouvez vous me donner un contre exemple ?
    Merci :-)

  2. #2
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 752
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 752
    Points : 10 683
    Points
    10 683
    Billets dans le blog
    3
    Par défaut
    Si tu te contente du premier test, la chaine suivante va etre reconnue comme un entier: "1234coucou". Donc il faut un 2° test pour vérifier, après extraction du nombre, qu'il ne reste plus rien => que l'extraction d'une chaine après le nombre échoue.

  3. #3
    Membre habitué Avatar de SteelBox
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    446
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Novembre 2002
    Messages : 446
    Points : 194
    Points
    194
    Par défaut
    Effectivement, j'aurais du faire le test.
    J'ai compris le fonctionnement.

    D'ailleurs, ca serait peut être intéressant de le mettre dans la partie String de la FAQ C++..

    Merci

  4. #4
    Membre à l'essai
    Inscrit en
    Septembre 2004
    Messages
    25
    Détails du profil
    Informations forums :
    Inscription : Septembre 2004
    Messages : 25
    Points : 22
    Points
    22
    Par défaut
    Autrement , pour lire un int en le filtrant dans une chaine de caractères
    et en maitrisant les overflow.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
     
    #include <iostream>
    #include<string>
    #include<math>
    using namespace std;
    char *mini;
    int nombre_de_chiffes(unsigned int n) {
            if(n<=9) return 1;
            else return nombre_de_chiffes((n-n%10)/10)+1;
       }
    void int_to_chaine(int n,char *res){
            if(n<0) {
                  char *q=new char[1];
                  int_to_chaine(-n,q);
                  *res='-';*(res+1)='\0';
                  strcat(res,q);
            }   
            else if(n<=9) {
                *res=char('0'+n);*(res+1)='\0';
            }
            else {
               char *ch=new char[1];
               int_to_chaine((n-n%10)/10,res);
               int_to_chaine(n%10,ch);
               strcat(res,ch);
            }
       }
    void plus_petit_int_en_chaine() {
         mini=new char[1];
         int_to_chaine(-numeric_limits<int>::max(),mini);
         int p=nombre_de_chiffes(numeric_limits<int>::max());
         if(*(mini+p)!='9') *(mini+p)=char(*(mini+p)+1);
         else {cout<<"plantage";exit(-1);}
    }    
     
     
    bool depassement_capacite(char *c) {
            char *maxi=new char[1];
            int_to_chaine(numeric_limits<int>::max(),maxi);
                     if ( strlen(c)>strlen(maxi) )  return true;
                     else if ( strlen(c)<strlen(maxi) ) return false;
                     else if (strcmp(c,maxi)<=0) return false;
                     else return true;
       }
     
       char * tampon() {
       const max=100;//arbitraire
       cout<<"entrer un entier: ";
       char *ch=new char[max];
       cin.getline(ch,max);
       if(!cin) {cout<<"erreur";exit(-1);}
       return ch;
       }
       bool analyse_lexicale(char *ch,char &c) {
          int lg=strlen(ch);
          bool valide;
          c=ch[0];int i=1;
          valide=( c=='+' || c=='-' || (c>='0' && c<='9') );
          while(i<lg && valide ) {
             valide=(ch[i]<='9' && ch[i++]>='0');  
          }
          return valide;
       }
       int lecture_entier_sans_signe(char *c) {
           if(depassement_capacite(c)) {
                 cout<<"depassement des capacites:le plus grand int est: ";
                 cout<<numeric_limits<int>::max()<<endl;
                 exit(-1);
           }
           int res;int lg=strlen(c);
           if(lg==1) res=c[0]-'0';
           else res=(c[0]-'0')*pow(10,lg-1)+lecture_entier_sans_signe(c+1);
           return res;
       }
       void lecture_entier(int &n) {
           char *ch=tampon();
           char s;
           if(!analyse_lexicale(ch,s)){
               cout<<"erreur de saisie."<<endl;exit(-1);
           }
           plus_petit_int_en_chaine() ;
           if( strcmp(ch,mini)==0 ) n=numeric_limits<int>::min();
           else if(s=='-'||s=='+') {
               int signe=(s=='+')?1:-1;
               n=signe*lecture_entier_sans_signe(ch+1);
           }
           else n=lecture_entier_sans_signe(ch);
           cout<<"merci pour "<<n<<endl;
       }
     
     
    main() {
     int n;
     lecture_entier(n);
    }

    _____________________________________________________________
    la recurrence ça dépote
    pourquoi deleter quand le compilo peut le faire?

  5. #5
    Membre du Club
    Inscrit en
    Juin 2002
    Messages
    37
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 37
    Points : 42
    Points
    42
    Par défaut
    Citation Envoyé par porcher
    /* Un code en C et non en C++ */
    Ah ! concision et clarté du langage C, quand tu nous tiens

  6. #6
    Membre à l'essai
    Inscrit en
    Septembre 2004
    Messages
    25
    Détails du profil
    Informations forums :
    Inscription : Septembre 2004
    Messages : 25
    Points : 22
    Points
    22
    Par défaut
    Monsieur Paul Atreide,Futur(e) Membre du Club
    C'est peut etre du C mais c'est aussi du C++!!
    Quand à la concision c'est pas le but recherché ici.
    C'est juste pour réviser mes gammes.
    Y en a bien qui s'amusent à traverser l'atlantique à la rame, moi je m'amuse avec les char *.C'est tout!

  7. #7
    Membre du Club
    Inscrit en
    Juin 2002
    Messages
    37
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 37
    Points : 42
    Points
    42
    Par défaut
    Je me suis mal exprimé et je m'en excuse : il n'y avait aucune critique à ton égard porcher. Je m'amuse moi-même à écrire de temps du "bon vieux code" plein de pointeurs de pointeur, de char*, ... J'ai écris ce message car je pense que de nombreux débutants consultent ce forum et qu'il est "bien" de leur montrer que le C++ n'est pas une petite extension du C mais bien un concept différent (même si le C est un sous-ensemble du C++).

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    82
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 82
    Points : 71
    Points
    71
    Par défaut
    Pour un test, ces solutions me parraissent plutot gourmandes.

    Une simple fonction comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    inline bool is_number( const string& s )
    {
    	return count_if( s.begin(), s.end(), isdigit ) == s.size();
    }
    retourne vrai si le chaine représente un nombre entier positif.

    NB: Attention, cela ne teste pas les bornes... ajouter si besoin.

  9. #9
    Inactif  

    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    534
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 534
    Points : 403
    Points
    403
    Par défaut
    Bonsoir,

    Apparement la question initiale cherche à convertir une
    chaîne en numérique .

    Sujet maintes fois abordé .

    Essayons par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
    #include <iostream>
    #include <string>
    #include <sstream>
     
    #using namespace std;
     
     
    template< typename T >
    bool StrToNum( T& val , const string& s )
     {
       string tmp;
       string::size_type idx = s.find_last_not_of( ' ' );
       if ( idx != string::npos )
       tmp = s.substr( 0, idx + 1 );
     
       istringstream iss( tmp );
       T v;
       if ( ! (iss >> v ) || ! iss.eof() ) return false ;
       val = v ;
       return true;
     }
     
    int main()
    { int i ;
      string z ( "-21121" ) ;
      if( StrToNum( i, z ) == true )
      cout << "ok " << i  << endl ;
      else
      cout << "Mauvaise conversion " << endl ;
      return 0 ;
    }
    Cordialement.

  10. #10
    Membre habitué Avatar de SteelBox
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    446
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Novembre 2002
    Messages : 446
    Points : 194
    Points
    194
    Par défaut
    Apparement la question initiale cherche à convertir une
    chaîne en numérique .
    Faux ! c'est pas une conversion, c'est : savoir si une chaine est numérique.
    En plus, je demandais une explication, pas une solution...
    En tout cas, merci pour vos réponses, le problème est maintenant résolu

  11. #11
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 752
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 752
    Points : 10 683
    Points
    10 683
    Billets dans le blog
    3
    Par défaut
    La méthode propre c'est les expressions régulières.
    D'ailleurs, ca serait peut être intéressant de le mettre dans la partie String de la FAQ C++..
    On pourrait effectivement inclure cette remarque ici:
    http://c.developpez.com/faq/cpp/?pag...TRINGS_is_type

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [PHP 5.3] Comment savoir si une string est dans une variable
    Par pierrot10 dans le forum Langage
    Réponses: 1
    Dernier message: 29/10/2011, 15h08
  2. Réponses: 10
    Dernier message: 23/06/2011, 08h19
  3. Savoir si une string est une date.
    Par poly128 dans le forum Delphi
    Réponses: 3
    Dernier message: 15/05/2007, 23h10
  4. [VB6] [Impression] Savoir si une imprimante est installée
    Par Norm59ttp dans le forum Installation, Déploiement et Sécurité
    Réponses: 2
    Dernier message: 19/12/2002, 09h29

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo