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

 C++ Discussion :

vérifier l'input de l'utilisateur


Sujet :

C++

  1. #1
    Membre très actif
    Avatar de Snack3r
    Homme Profil pro
    Doctorant à l'Université Cheikh Anta Diop de Dakar
    Inscrit en
    Octobre 2013
    Messages
    118
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Mauritanie

    Informations professionnelles :
    Activité : Doctorant à l'Université Cheikh Anta Diop de Dakar
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2013
    Messages : 118
    Par défaut vérifier l'input de l'utilisateur
    Bonsoir

    Souvent on aura besoin de vérifier l'entrée de l'utilisateur pour des raisons de cohérence et de compatibilité, dans ce sujet on discutera la meilleure méthode pour vérifier qu'une chaine (fournie depuis le clavier) respecte la syntaxe d'un nombre réel ou pas.

    La méthode la plus simple est de faire la vérification à travers une méthode codée à la main comme celle là 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
    33
    #include <cctype>
    #include <cstdlib>
    #include <iostream>
    using namespace std;
     
    bool is_real_number(const char* number_string) {
        int counter = 0;
        while (*number_string) {
            char c = *number_string++;
            if (c == '.') {
                counter++;
                if (counter > 1)
                    return false;
            } else {
                if (!std::isdigit(c))
                    return false;
            }
        }
        return true;
    }
     
    int main() {
        char cbuf[20] = {0};
        cin.getline(cbuf, '\n');
        float num;
        if (is_real_number(cbuf)) {
            num = atof(cbuf);
            cout << num << endl;
        } else {
            cout << "ERROR !" << endl;
        }
        return 0;
    }
    et il existe d'autres méthodes comme le regex par exemple.

    A votre avis, quelle est la meilleure méthode pour vérifier que l'entrée du user respecte bien la syntaxe d'un nombre de type float ?


    Merci d'avance pour vos participations.

  2. #2
    Membre chevronné
    Inscrit en
    Juillet 2012
    Messages
    231
    Détails du profil
    Informations forums :
    Inscription : Juillet 2012
    Messages : 231
    Par défaut
    Salut,

    Pour moi, la méthode la plus simple (peut-être pas la meilleure, mais la plus simple en tout cas) c’est d’essayer de lire le nombre.
    En C on utiliserait strtod, en C++03 on passerait par les std::istringstream je pense.
    En C++11, on peut utiliser std::stod.
    En aucun cas on n’utilisera atof (même en C c’est déprécié, du moins dans les pages de man, pour les standards il faudrait vérifier) car cette fonction ne fait aucune gestion d’erreur.

    D’ailleurs ton code a un comportement bizarre chez moi : pour 0.00000001 en entrée il me renvoie 0.
    En plus, avec ta pré-vérification tu n’acceptes pas les formes suivantes : " 3.14", "1e-3", "1.1E-2", …

    J’ai rapidement fait une version avec std::stod.
    Code C++ : 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
    #include <iostream>
    #include <string>
    #include <stdexcept>
     
    int main()
    {
        std::string input;
     
        std::cin >> input;
        try
        {
            std::string::size_type sz;
            float d = std::stof(input, &sz);
            std::cout << d << '\n';
        }
        catch (std::out_of_range err)
        {
            std::cerr << "Number is too big (or too small): " << err.what() << '\n';
        }
        catch (std::invalid_argument err)
        {
            std::cerr << "ERROR: the string is not a number!\n";
        }
     
        return 0;
    }
    Avec 0.00000001 en entrée ça me renvoie 1e-08
    Avec des espaces avant j’obtiens bien 3.14
    Avec 1e-3 j’ai 0.001
    Avec 1.1E-2 j’ai 0.011

  3. #3
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 292
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 292
    Par défaut
    Je ne passerai même pas par une chaine intermédiaire, et utiliserai directement >>.
    Et la FAQ, devinez-quoi, contient tout ce qu'il faut sur ce sujet...
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  4. #4
    Membre très actif
    Avatar de Snack3r
    Homme Profil pro
    Doctorant à l'Université Cheikh Anta Diop de Dakar
    Inscrit en
    Octobre 2013
    Messages
    118
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Mauritanie

    Informations professionnelles :
    Activité : Doctorant à l'Université Cheikh Anta Diop de Dakar
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2013
    Messages : 118
    Par défaut
    ton code a un comportement bizarre chez moi : pour 0.00000001 en entrée il me renvoie 0.
    Au lieu de atof, je vais utiliser std::stringstream pour convertir le char* en float :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    float to_float(const char *p) {
        std::stringstream ss(p);
        float result = 0;
        ss >> result;
        return result;
    }
    c'est valable pour 1e-007 mais pas pour 1e-008, je sais pas pourquoi !

    avec ta pré-vérification tu n’acceptes pas les formes suivantes : " 3.14", "1e-3", "1.1E-2", …
    C'est vrai, j'ai pas prêté attention à ce point là même si c'est pertinent.
    Je pense que si on veut accepter les formes des réels, ce sera un peu difficile. pour cela souvent on profite des fonctions prédéfinies du C++.

    J’ai rapidement fait une version avec std::stod.
    c'est bien, +1.

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

Discussions similaires

  1. Vérifier l'authentification d'un utilisateur
    Par Kishin dans le forum Langage
    Réponses: 1
    Dernier message: 03/12/2008, 14h17
  2. Réponses: 2
    Dernier message: 28/05/2008, 09h59
  3. Vérifier l'existence d'un utilisateur dans l'Active drectory
    Par dev_gahie dans le forum Général Java
    Réponses: 3
    Dernier message: 14/04/2008, 17h36
  4. Vérifier le choix d'un utilisateur sur un MessageBox
    Par CleeM dans le forum Windows Forms
    Réponses: 8
    Dernier message: 25/02/2008, 16h16
  5. [BATCH] récupérer l'input de l'utilisateur
    Par Galevsky dans le forum Windows
    Réponses: 2
    Dernier message: 16/01/2008, 22h57

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