Vérification de saisie de float en C !

bonjour,
je viens de passer du C++ au bon vieux C et je m’apperçoit que je bloque pour programmer à peu près proprement :stuck_out_tongue:

En fait, j’aimerais créer la fonction GetFloat qui prend un paramètre-résultat de type float et qui renvoit un bool ( true si la personne n’a pas saisie EOF, false dans le cas contraire ). Elle me permettrait de pouvoir récupérer facilement des floats par exemple de la façon suivante :


for ( i = 0; GetFloat (Tab[i]); i++ );

Le problème est que je n’arrive pas à trouver la bonne manière de l’écrire :

voici grossièrement la stratégie :


bool GetFloat ( float Float ) 
{
    déclarer Chaine_de_Caractère; 
    tant que 
       lecture au clavier stockée dans chaine de caractère n'est pas au format float [par exemple 5.1 ou 5e-1 etc ...] ( cas 1 ) -----  ou que l'utilisateur n'a pas envoyer EOF ( cas 2 ) )
   fin tant que

   Cas 1 : (Float = Chaine_de_Caractère convertie en float ) puis renvoyer true
   Cas 2 : renvoyer false 
}

Le problème est que j’utilisait scanf. Or je ne connais pas de fonction qui permettent de vérifier ( et de convertir) si une chaine de caractère est bien au format float ( et il y a bcp de tests à effectuer à cause de la présence possibles à différents endroits des signes “+, - e” ).

Merci d’avance pour votre aide ,

mike

IEEE 754 :wink:

Mais si tu en connais une :slight_smile:

strtof !

http://www.hmug.org/man/3/strtof.php

ex:

char s = "1errr";
char* t;
float f = strtof(s, &t);

if ( t != '\0' 
  printf( "erreur\n" );
else
  printf( "valeur = %g\n", f);

Tiens je ne conaissais pas strtof, j’utilise toujours : atof, mais c’est vrai qu’il n’y a pas la vérification, par exemple pour :

#include <stdlib.h>
int main()
{
     float f = atof("45.12test");
     printf("%g\n", f);
     return 0;
}

on a en retour :

mirs@r4penroc% ./temp
45.12

mais pas d’erreur pour dire que le reste de la chaine est “pourri”.
:kimouss:

Bonjour, voici mon code ! apparement il tourne niquel sous windows compilé sous dev cpp , mais ne passe pas sous linux avec CC ! ( true et false sont défini en enum et fonctionne ) ( je pense qu’il y a un soucis avec les pointeurs , par exemple des dépassement de tableau ! )

Exemple d’erreur sous linux :

Veuillez rentrer au maximum 100 entiers. Pour ne pas aller jusqu’à cette limite, entrez fin de fichier
Veuillez entrer un nombre ( EOF pour terminer la saisie) : 5
DEBUG : chaine récupérée par GetFloat() : 5
DEBUG : Valeur récupérée par GetFloat() : 2097152.000000
Veuillez entrer un nombre ( EOF pour terminer la saisie) : -4.2
DEBUG : chaine récupérée par GetFloat() : -4.2
DEBUG : Valeur récupérée par GetFloat() : 419430.000000
Veuillez entrer un nombre ( EOF pour terminer la saisie) : 6
DEBUG : chaine récupérée par GetFloat() : 6
DEBUG : Valeur récupérée par GetFloat() : 4194304.000000
Veuillez entrer un nombre ( EOF pour terminer la saisie) : 1
DEBUG : chaine récupérée par GetFloat() : 1
DEBUG : Valeur récupérée par GetFloat() : 0.000000
Veuillez entrer un nombre ( EOF pour terminer la saisie) : 2
DEBUG : chaine récupérée par GetFloat() : 2
DEBUG : Valeur récupérée par GetFloat() : 0.000000
Veuillez entrer un nombre ( EOF pour terminer la saisie) : 8
DEBUG : chaine récupérée par GetFloat() : 8
DEBUG : Valeur récupérée par GetFloat() : 0.000000
Veuillez entrer un nombre ( EOF pour terminer la saisie) : -4
DEBUG : chaine récupérée par GetFloat() : -4
DEBUG : Valeur récupérée par GetFloat() : 0.000000
Veuillez entrer un nombre ( EOF pour terminer la saisie) : 4E-5
DEBUG : chaine récupérée par GetFloat() : 4E-5
DEBUG : Valeur récupérée par GetFloat() : nan
Veuillez entrer un nombre ( EOF pour terminer la saisie) : 8
DEBUG : chaine récupérée par GetFloat() : 8
DEBUG : Valeur récupérée par GetFloat() : nan
Veuillez entrer un nombre ( EOF pour terminer la saisie) : 9
DEBUG : chaine récupérée par GetFloat() : 9
DEBUG : Valeur récupérée par GetFloat() : nan
Veuillez entrer un nombre ( EOF pour terminer la saisie) : 12
DEBUG : chaine récupérée par GetFloat() : 12
DEBUG : Valeur récupérée par GetFloat() : nan

( semble rester sur nan ) !

exemple de

 
int GetFloat ( float * Resultat )
{
    char Input [100];
    float F;
    char * EndPtr;
    int IsNaN = true;

    while ( IsNaN )
    {
        printf( "Veuillez entrer un nombre ( EOF pour terminer la saisie) : " );

        if ( EOF ==  scanf ( "%s", Input ) )  return false;
        /* CAS OU LA PERSONNE ENVOIE LE SIGNAL EOF */

        #if defined __DEBUG__
            printf ("__DEBUG__ : chaine récupérée par GetFloat() : %s \n", Input );
        #endif

        F = strtof ( Input, &EndPtr );


        /*
            Transformation de la NTCTS reçue en float. La fonction strtof() est
            standard, optimisée et permet d'accepter de nombreux formats
            d'entrée par exemple -1.334E-4
        */

        if ( ( (*EndPtr) != '\0' ) || ( Input == EndPtr ) )
        {
            printf ( "Valeur incorrecte !\n" );
            continue;
        }

       /*
            Strtof() renvoie un float égal à 0 si la conversion s'est mal
            passée. Elle convertit la chaine jusqu'à trouvé un caractère
            parasite. Si la chaine entrée est correcte, on aura donc
            PtrFin == '\0'
        */

        else
        {
                #if defined __DEBUG__
                    printf ("__DEBUG__ : Valeur récupérée par GetFloat() : %f \n", F );
                #endif
                IsNaN = true;
        }
        /*
            Si les tests ont étés effectués avec succès, alors l'input est
            correct
        */
    }

    (*Resultat) = F;
    return true;

} // GetFloat ()

Essaye en mettant IsNan = false juste après le while. Là, quand tu tombe sur un flottant foireux, tu mets la constante à true, et jamais elle ne revient à false. Et continue = va à la prochaine itération.

Au fait, IsNan = Is not a number? Donc si IsNan = true, tu n’as pas lu de nombre valide hein?

Exact pour le nan, j’avais fais ça à la vas vite avt de copier le poste :stuck_out_tongue: mais meme sans ça , ça foirait ! et j’ai trouvé la solution … en rajoutant la ligne

-Wall -std=c99 !

Connaissiez vous cela ??? Je pensais que GCC se mettait automatiquement en norme C99 ? ? ? ?

MErci d’avance :stuck_out_tongue: