begin process at 2013 05 22 02:14:20
  Trouver un code source :
 
dans
 
Accueil > 

Tutoriels

 > 

Chaîne de caractères

 > GÉRER LES ERREURS DE SAISIE

GÉRER LES ERREURS DE SAISIE


 Information sur le tutoriel

Note :
Aucune note

 Description

Ce petit tutoriel, sous forme de fonctions commentées, montre comment gérer des erreurs de saisie (en console par exemple).
Les 2 fonctions ci-dessous détaillent un des modes opératoires possibles.
Elles sont fonctionnelles, écrites sans l'utilisation d'espaces de noms et nécessitent l'include <sstream> pour que l'istringstream et l'ostringstream puissent fonctionner.

Tutorial

//--------------------------------------------------------------------------------------------

int entier() // demande d'un entier.

{

    std::string saisie;

    std::string verif;

    bool good = 1;

    bool trouble = 0;

    int num;

    do

    {

    if(good == 0){std::cout << "\n-> Saisie incorrecte, ressaisissez: ";}

    std::cin >> saisie;

    std::istringstream iss(saisie);

    iss >> num; // conversion du type string en type int.

    if(iss.fail()) // lorsqu'on insère uniquement des caractères lettre, le passage dans un type numérique ==> 0 , ce qui ne déclenche pas nécessairement d'anomalie lors de l'exécution (notamment lors de la saisie d'un seul caractère (lettre) ) alors même qu'il y a une erreur. D'où l'instauration du iss.fail(), permettant de s'abstenir de réaliser la procédure de vérification ci-dessous qui, à cause de cette conversion, ne verrait pas nécessairement une différence de taille entre le string saisie et le string verif.

    {

    good = 0;

    trouble = 1;

    }

    else // le cas où il n'y a pas que des caractères lettres, mais des caractères numériques suivit de lettres puis à nouveau de chiffres (ou pas).

    {

    std::ostringstream oss;

    oss << num; // conversion du type int en type string.

    verif = oss.str(); // retourne une copie de l'objet string équivalent à ce qui est dans le buffer (lorsqu'on entre par exemple 2e3, comme cela peut faire 2000, il n'y aura pas d'erreur à retourner).

    if(verif.size() < saisie.size()) // lors du passage dans la variable num, les caractères autres que numérique sont enlevés par stringstream, par conséquent, lorsqu'on met le contenu de num dans un autre string, la taille des 2 strings sera différente.

    {

    good = 0;

    trouble = 1;

    }

    else{good = 1;}

    }

    if(good == 1 && trouble == 1){std::cout << "-> OK!" << std::endl;}

    }while(good == 0);

    return num;

}

//------------------------------------------------------------------------------------------

double reel() // demande d'un réel

{

    std::string saisie;

    std::string verif;

    size_t found; // type de variable spécifiquement utilisé pour le traitement d'une chaine de caractères en fonction de sa taille.

    bool good=1;

    bool trouble=0;

    double num;

    do

    {

    if(good == 0){std::cout << "\n-> Saisie incorrecte, ressaisissez: ";}

    std::cin >> saisie;

    found = saisie.find_first_of(","); // on va chercher dans la chaine saisie si il y a une virgule française, si il n'y en a pas, nous seront à npos (fin de chaîne)

    while (found != std::string::npos) // mais si il y en a, tant que nous ne seront pas arrivés à la fin de la chaine...

    {

    saisie[found] = '.'; // ...la virgule française sera transformée en point...

    found = saisie.find_first_of("," , found+1); // ... tant qu'il y en aura, afin d'arriver à la fin de la chaîne. (bien que cela ne soit pas nécessairement utile en soi...)

    }

    // tout ce qu'il y a en dessous est identique à la fonction entier() mais pour les doubles.

    std::istringstream iss(saisie);

    iss >> num;

    if(iss.fail())

    {

    good = 0;

    trouble = 1;

    }

    else

    {

    std::ostringstream oss;

    oss << num;

    verif = oss.str();

    if(verif.size() < saisie.size())

    {

    good = 0;

    trouble = 1;

    }

    else{good = 1;}

    }

    if(good == 1 && trouble == 1){std::cout << "-> OK!" << std::endl;}

    }while(good == 0);

    return num;

}

//------------------------------------------------------------------------------------------------

 Historique

16 février 2011 01:54:19 :
Correction d'une faute.
16 février 2011 01:57:53 :
Rectification d'une erreur de commentaire.
16 février 2011 02:12:06 :
Modification d'un commentaire.
16 février 2011 12:27:53 :
Essai de rajout des alinéas.
16 février 2011 12:29:34 :
Essai de rajout des alinéas.
16 février 2011 12:39:27 :
Essai de rajout des alinéas
16 février 2011 12:42:20 :
Essai de rajout des alinéas.
16 février 2011 12:43:01 :
.
17 février 2011 19:48:48 :
Modification d'un commentaire trop succinct.
17 février 2011 19:51:54 :
.
17 février 2011 19:56:18 :
.
17 février 2011 19:59:42 :
Rajout de 2 couleurs.

Commentaires

Commentaire de beg0 le 13/03/2011 14:32:43

Snippet intéressant, ne serait il pas possible d'utiliser des templates?

Commentaire de Minilogus le 13/03/2011 18:40:31

Eh bien j'ai fait cette classe, toutefois elle n'est pas compatible avec 100% des compilateurs...

//------------------------------------------------------------ Fichier: saisie.h ------------------------------------------------------------

#ifndef SAISIE_H_INCLUDED
#define SAISIE_H_INCLUDED

#include <iostream>
#include <sstream>
#include <typeinfo>

template<typename numbr3s>
class saisie
{
    public:

        void nb(numbr3s &);
};


template<typename numbr3s>
void saisie<numbr3s>::nb(numbr3s &num)
{
    std::string saisie;
    std::string verif;

    std::string type; // stockage du "nom" du type de variable.
    std::string positif = ""; // positif ou négatif.
    std::string entier = ""; // entier, réel, non numérique.

    size_t found;
    bool good = true;
    bool trouble = false;

    numbr3s num1;

    type = typeid(numbr3s).name(); // typeid nécessite #include<typeinfo>. typeid(numbr3s).name() renvoie le nom du type numbr3s. Ex, si numbr3s est un int, int sera renvoyé, bien qu'en réalité (selon la norme utilisé par le compilateur) cela peut être un "i".

if(type.size() == 1) // sécurité compatibilité (Typeid, avec gcc par exemple, ne renvoie qu'une lettre).
{
found = type.find_first_of("def"); // d = double  ;  e = long double  ;  f = float  .
if(found != std::string::npos){entier = " nombre";}
else
{
found = type.find_first_of("islx"); // i = int  ;  l = long int  ;  x = long long int  ;  s = short int  .
if(found != std::string::npos)
{
entier = " entier";
positif = " (+/-) ";
}
else
{
found = type.find_first_of("jtmy"); // j = unsigned int  ;  m = unsigned long int  ;  y = unsigned long long int  ;  t = unsigned short int  . Un else aurait pu suffir, mais on peut toujours oublier un type de variable, ou la fonction TypeId ne renvoie pas forcément quelque chose de convenable en fonction du compilateur.
if(found != std::string::npos)
{
entier = " entier";
positif = " (+) ";
}
}
}
}


    do
    {
        if(good == false)
        {
            std::cout << std::endl << "-> Saisie incorrecte, ressaisissez";
            if(positif != ""){std::cout << " {un" << entier << positif << "}";}
            std::cout << ": ";
        }

        std::cin >> saisie;

        if(entier != " entier" && positif != "")
        {
            found = saisie.find_first_of(",");
            while(found != std::string::npos)
            {
                saisie[found] = '.';
                found = saisie.find_first_of("," , found+1);
            }
        }

        if(positif != "" && saisie[0] == '-')
        {
            good = false;
            trouble = true;
        }
        else
        {
            std::istringstream iss(saisie);
            iss >> num1;

            if(iss.fail())
            {
                good = false;
                trouble = true;
            }
            else
            {
                std::ostringstream oss;
                oss << num1;

                verif = oss.str();

                if(verif.size() < saisie.size())
                {
                    good = false;
                    trouble = true;
                }
                else{good = true;}
            }

            if(good == true && trouble == true)
            {
                std::cout << "-> OK!" << std::endl << std::endl;
            }
        }

    }while(good == false);

    num = num1;
}


#endif

//----------------------------------------------------------------------------------------------------------------------------------------------

//------------------------------------------------------------ Fichier: main.cpp ------------------------------------------------------------

#include <iostream>

#include "saisie.h"

int main()
{
    std::cout << ">-------------------- ^_^ --------------------<\n" << std::endl;
    double val; // choisissez votre type (ici double)
    saisie<double> d; // puis recopiez le entre les < >

    std::cout << "Entrer une valeur:  ";
    d.nb(val);
  
    std::cout << "Vous avez entré: " << val << "\n>--------------------------------------------------------------<" << std::endl;
    return 0;
}

//----------------------------------------------------------------------------------------------------------------------------------------------

Commentaire de ZeRo0Cold le 28/05/2011 08:49:40

merci bcp

Commentaire de ZeRo0Cold le 28/05/2011 08:51:10

svp il y a ce code en langage C

Commentaire de Minilogus le 10/06/2011 18:20:28

Non je n'ai pas porté ce code en langage C, il y aurait un désaventage en terme de temps d'exécution par rapport au C++ pour ce genre de chose (=> string vs char).

 Ajouter un commentaire




Nos sponsors


Sondage...

CalendriCode

Mai 2013
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
2728293031  

Consulter la suite du CalendriCode

Photothèque

A découvrir



 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 3,853 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales