Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
4763 connectés 

 


Dernière réponse
Sujet : Débutant en C >>> veux obliger une saisie en int sans que ça plante
Aricoh BiFace, chacun son opinion
 
je n'ai besoin de cette fonction, uniquement pour que mon programme se prémunisse d'une saisie incorrecte par un abruti, rien de +
 
Le programme demande un int et le type tape des lettres, c'est lui qui se fait jeter et pas mon programme qui plante !

Votre réponse
Nom d'utilisateur    Pour poster, vous devez être inscrit sur ce forum .... si ce n'est pas le cas, cliquez ici !
Le ton de votre message                        
                       
Votre réponse


[b][i][u][strike][spoiler][fixed][cpp][url][email][img][*]   
 
   [quote]
 

Options

 
Vous avez perdu votre mot de passe ?


Vue Rapide de la discussion
Aricoh BiFace, chacun son opinion
 
je n'ai besoin de cette fonction, uniquement pour que mon programme se prémunisse d'une saisie incorrecte par un abruti, rien de +
 
Le programme demande un int et le type tape des lettres, c'est lui qui se fait jeter et pas mon programme qui plante !
BifaceMcLeOD

Aricoh a écrit a écrit :

 
 
deux exemples :
 
si le bourrin tape a10, la fonction atoi s'arrête au 'a' et retourne 0
si le bourrin tape 10a, la fonction prend '10' et retourne 10, le 'a' passe à la trappe
 
j'ai testé et ça marche




Oui, c'est exactement ce à quoi je m'attendais. Mais je ne considère pas "10a" et "a10" comme des saisies correctes...
 
Ceci dit, tu fais ce que tu veux...  :)

Aricoh Voici ma fonction qui utilise le ascii to int (atoi, oui oui, je sais que vous le savez, c'est juste pour me la pêter un dixième de sec :p  ) :
 
void verif_int (int *a, int nbre)
{
 char buffer[80],
      tablo[nbre+1];
 
 buffer[0] = '\0';
 tablo[0] = '\0';
 
 gets(buffer);
 strncpy(tablo, buffer, nbre);
 *a = atoi(tablo);
 return;
}
 
J'utilise cette fonction pour deux cas de figure :
 
je ne veux en retour qu'un seul nombre, ou bien deux chiffres
 
La variable nbre que je transmet en paramètres à ma fonction peut prendre 1 comme valeur ou 2
 
le tout fonctionne
Aricoh

BifaceMcLeOD a écrit a écrit :

Question bête : si tu tapes "10a", ton filtrage, il marche toujours ? Je n'en suis pas si sûr...




 
deux exemples :
 
si le bourrin tape a10, la fonction atoi s'arrête au 'a' et retourne 0
si le bourrin tape 10a, la fonction prend '10' et retourne 10, le 'a' passe à la trappe
 
j'ai testé et ça marche

BifaceMcLeOD Question bête : si tu tapes "10a", ton filtrage, il marche toujours ? Je n'en suis pas si sûr...
Aricoh J'm'a gourré dans le code ci-dessus, l'initialisation du tableau de char est fausse, il faut plutôt lire :
 
tablo[0] = '\0';
Aricoh Ok, le code ci-dessous fonctionne :
 
char tablo[20];
int reponse;
 
do
{
    tablo[0] = "";
    reponse = 0;
    printf ("Donnez une valeur comprise entre 3 et 21 : " );
    gets(tablo);
    reponse = atoi(tablo);
    if (reponse < 3 || reponse > 21)
        printf ("valeur incorrecte\n" );
    printf ("reponse vaut %d\n", reponse);
}    while (reponse < 3 || reponse > 21);
    printf ("résultat OK, boucle terminée\n" );
 
 
Quelques exemples de fonctionnement :  
 
Donnez une valeur comprise entre 3 et 21 : c
valeur incorrecte
reponse vaut 0
Donnez une valeur comprise entre 3 et 21 : 1221
valeur incorrecte
reponse vaut 1221
Donnez une valeur comprise entre 3 et 21 : 2.75
valeur incorrecte
reponse vaut 2
Donnez une valeur comprise entre 3 et 21 : 134d kyz
valeur incorrecte
reponse vaut 134
Donnez une valeur comprise entre 3 et 21 : 12.27x
reponse vaut 12
résultat OK, boucle terminée
 
C'était donc bien atoi() qu'il fallait que j'utilise pour faire au + simple
 
oui oui, je sais, avec mon tablo, je ne suis pas protégé d'un fou qui taperait 50 caractères, vi vi, je sais :)
 
j'y travaille, merci à tous pour vos conseils, vous m'avez mis sur la piste qu'il fallait, cool !
 
Salut FHR, ça roule ? ;)
BifaceMcLeOD

trasfract a écrit a écrit :

Moi je pencherais plutôt pour un atoi comme seb. Il y a des fonctions dédiées, autant les utiliser !




atoi marche très bien tant que la chaine en entrée est correcte.

Pschitt Pourquoi convertir du char en int ?
 
On peut utiliser la valeur retournée par scanf pour tester la saisie :
 
 - 0 si char  
 - 1 si int ou float
 
Si l'utilisateur saisi des caractères on vide le buffer clavier pour ne pas planter scanf :
 
void main()
 
{float reponse;
 int r;
 reponse=1;
 r=0;
 
 while(reponse)
 
        {printf("Saisir une valeur (0 pour terminer) : " );
 
         r=scanf("%f",&reponse);
 
         if(r && reponse>=3 && reponse<=21)
 
            printf("Valeur OK\n" );
 
         else
 
            {printf("Valeur impossible\n" );
             while(getchar()!='\n'); /*Vidage buffer*/
            }
        }
}
fhr Salut Aricoh !
Quoi de neuf ?
 
Désolé, j'ai pas de réponse pour toi..
trasfract Moi je pencherais plutôt pour un atoi comme seb. Il y a des fonctions dédiées, autant les utiliser !
BifaceMcLeOD Dans l'idée, c'est darkoli qui présente la meilleure solution. Maintenant pour le code lui-même, désolé, mais il est à s'arracher les cheveux... Je te propose de modifier son code comme suit :
 

Code :
  1. #include <string.h>
  2. #include <ctype.h>
  3. typedef int BOOL;
  4. #define TRUE  1
  5. #define FALSE 0
  6. int  entier = lis_entier(3, 21);
  7. int lis_entier(int borneMin, int borneMax) {
  8.     char  chaine[255];
  9.     int   entier = 0;
  10.     BOOL  OK;
  11.     int   i;
  12.     do {
  13.         OK = TRUE;
  14.         scanf("%s", chaine);
  15.         /* On déchiffre l'entier. */
  16.         for (i = 0; i < strlen(chaine); i++) {
  17.             if (!isdigit(chaine[i])) {
  18.                 /* Si un des caractères lus n'est pas un chiffre, on arrête de déchiffrer. */
  19.                 OK = FALSE;
  20.                 break;
  21.             }
  22.             entier = 10 * entier + (chaine[i] - '0');
  23.         }
  24.         /* Si on a bien lu un entier, on teste s'il est dans les bornes. */
  25.         if (OK  &&  (entier < borneMin  ||  entier > borneMax)) {
  26.             OK = FALSE;
  27.         }
  28.         /* On affiche un message d'erreur si la saisie est incorrecte. */
  29.         if (!OK) {
  30.             printf("Saisie incorrecte. Veuillez entrer un nombre entier compris entre %d et %d.\n",
  31.                    borneMin, borneMax);
  32.         }
  33.     } while (!OK);
  34.     return entier;
  35. }
 

[edit]--Message édité par BifaceMcLeOD--[/edit]

Aricoh Merci pour les 3 exemples les gars, cool ! doit bien y avoir l'une de vos méthodes qui fonctionne :)
 
pour le isdigit(), j'y avais pensé mais ne voyait pas trop comment le mettre en oeuvre
 
par contre, pour le atoi(), je vais essayer !
Amadeus Pourquoi tu n'utiliserais pas un compteur qui terminera la boucle au bout d'un certain nb d'essais :
int nb_essais=10;
do  
{  
printf ("Donnez un nombre compris entre 3 et 21 : " );  
scanf ("%d", &reponse); /*<- la conversion en int est implicite ici (%d) : 2.2 devient 2 */
if (reponse>=3 && reponse<=21) { break; }
} while (nb_essais-- > 0);
if (nb_essais) { printf("Ok\n" ); }
seblamb Sinon il y a d'autres fonctions pour ce que tu veux faire
 deja isdigit pour savoir si c'est un chiffre ( plus sympa qu'un tableau)
 sinon atoi qui permet egalement de convertir une chaine en entier sans planter.
darkoli en fait je crois que la solution est :
 

Code :
  1. int lire=0;
  2. do {
  3.   lire=Lire_Nombre_3_21();
  4. } while (lire==0);
  5. int Lire_Nombre_3_21(void) {
  6.   char s[255];
  7.   int  l;
  8.   cahr c;
  9.   int  n;
  10.   scanf("%s",s);
  11.   l=strlen(s);
  12.   if (l<1) return(0); 
  13.   c=s[0];
  14.   if ((c>47) && (c<58)) {
  15.     n=c-48;
  16.     }
  17.   else {
  18.     return(0);
  19.     }
  20.   if (l>1) {
  21.     c=s[1];
  22.     if ((c>47) && (c<58)) {
  23.       n=n*10+(c-48);
  24.       }
  25.     else {
  26.       return(0);
  27.       }   
  28.     }
  29.   if (n<3) return(0);
  30.   if (n>23) return(0);
  31.   return(n);
  32. }


 
voila qqc qui devrait marcher, ca fait un peu bidouille et jepense qu'il existe surement de meilleure solution, mais c'est deja une solution

Aricoh Mog, à la base, j'avais fait mon do while exactement comme l'exemple que tu as montré
 
C'est quand j'ai vu que ça plantait par exemple en tapant 2.1 que j'ai cru qu'avec un tableau pour comparer, le problème allait disparaître
 
donc oui, je me complique la vie avec mon propre exemple, puisque lui comme le tiens ne fonctionnent pas
mog Tu te complique la vie ou g pas compris ce ke tu veux faire:
 
do {  
  printf ("Donnez un nombre compris entre 3 et 21 : " );  
  scanf ("%d", &reponse);  
} while ((reponse < 3) || (reponse > 21));
 
Ca devrais suffire.
 
Y'aura peut-êrte une conversion float->int à faire, je sais pû trop !
Aricoh up
Aricoh Voici le bout de code actuel, comment verriez-vous le truc ?
 
int tablo[19] = {3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21},
 reponse = 0,
 i,
 etat;
 
etat = 0;
do
{
 printf ("Donnez un nombre compris entre 3 et 21 : " );
 scanf ("%d", &reponse);
 i = 0;
 while (i < 19)
 {
  if (reponse != tablo[i])
   ++i;
  else
  {
   etat = 1;
   break;
  }
 }
} while (etat != 1);
darkoli ben tu lis une chaine de caracteres et ensuite tu fais toi meme la conversion. Je  crois que dans ce cas c'est la solution la plus simple.
Aricoh mon problème va vous sembler tout simple :
 
j'ai un int appelé reponse;
 
reponse doit être compris entre 3 et 21
 
je demande à l'utilisateur de saisir un nombre compris entre ces valeurs
 
à côté, j'ai un tableau d'int contenant toutes ces valeurs, une fois reponse mis à jour par le mec, je vérifie que la valeur saisie corresponde bien à l'une des valeurs de mon tableau de concordance
 
si le mec tape 3, ça fonctionne
si le mec tape 3.2, ça fonctionne aussi (normal)
si le mec tape 2, je l'envoie bouler
si le mec tape 34, je l'envoie bouler
 
quand reponse == int, ça marche
 
si maintenant le mec tape 2.2, ça plante (je suis dans une boucle, je n'en sors pas)
si le mec s'amuse à taper 'c' (enfin, un char quoi), même problème
 
pour une saisie en float, je pense faire un cast pour forcer la conversion en int avant de tester la valeur avec le tableau de concordance
 
mais si c'est un caractère non numérique ?
 
Z'avez une 'tite idée toute simple ?

Copyright © 1997-2025 Groupe LDLC (Signaler un contenu illicite / Données personnelles)