Pages : 1
#1 Le 01/12/2007, à 19:25
- guguscat
[résolu] Saisie sécurisée en C
Bonjour à tous,
En fait j'ai un problème de saisie sécurisée en C.
J'effectue une saisie avec scanf, et la fonction scanf permet de renvoyer une valeur 0 ou 1 si la saisie est bonne ou pas.......
donc dans ma boucle je met comme condition de continuer si la valeur renvoyée par scanf est de 0.
Et ce qui se passe c'est que si la saisie est bonne, alors "tout va pour le mieux dans le meilleur des mondes". Voltaire, Candide, chapitre 30
Mais si je rentre par exemple un caractère, alors ma boucle se répète indéfinniment sans que je puisse effectuer à nouveau la saisie.
Je ne comprends pas trop pourquoi, si il y aurait quelqu'un pour m'expliquer je lui serais très reconnaissant.
#include <stdio.h>
#include <stdlib.h>
int main()
{
long saisie, truc;
do
{
printf("\nSaisir truc : ");
fflush(stdin);
saisie=scanf("%ld", &truc);
} while(saisie!=1);
printf("\nTruc = %ld", truc);
return 0;
}
Dernière modification par guguscat (Le 02/12/2007, à 20:45)
Un problème non résolu ? Indiquez le en insultant les gens qui tentent de vous aider.
Hors ligne
#2 Le 01/12/2007, à 20:40
- abetsic
Re : [résolu] Saisie sécurisée en C
Tu es sûr que scanf renvoie 1 ? fais un printf o๠tu affiches la valeur de ta variable saisie.
Hors ligne
#3 Le 01/12/2007, à 20:57
- tructu
Re : [résolu] Saisie sécurisée en C
ben d'apres le man de scanf :
Ces fonctions renvoient le nombre d’éléments d’entrées correctement mis
en correspondance et assignés. Ce nombre peut être plus petit que le
nombre d’éléments attendus, et même être nul, s’il y a une erreur de
mise en correspondance.La valeur EOF est renvoyée si la fin de l’entrée est atteinte avant la
première conversion réussie ou si un échec de correspondance survient.
EOF est également renvoyé si une erreur de lecture survient, auquel cas
l’indicateur d’erreur pour le flux (voir ferror(3)) est positionné et
errno est remplie en conséquence
#4 Le 01/12/2007, à 21:13
- guguscat
Re : [résolu] Saisie sécurisée en C
Tu es sûr que scanf renvoie 1 ? fais un printf o๠tu affiches la valeur de ta variable saisie.
En effet, j'ai fait un printf pour voir la valeur renvoyée, et il s'avère que la valeur était de 1 quand j'effectuais une saisie valable et de 0 lorsque la saisie était mauvaise (par exemple quand je saisie un caractère).
Ce que je ne peux pas comprendre en revanche, c'est que lorsque j'effectue une saisie "mauvaise", la boucle se répète indéfiniment sans que je refasse de saisie alors que je devrais pouvoir refaire une saisie justement.
bon :
Saisir truc : 12
Truc = 12
pas bon :
Saisir truc :
Saisir truc :
Saisir truc :
Saisir truc :
Saisir truc :
Saisir truc :
Saisir truc :
Saisir truc :
Saisir truc :
Saisir truc :
Saisir truc :
Saisir truc :
Saisir truc :
Saisir truc :
Saisir truc :
Saisir truc :
Saisir truc :
Saisir truc :
Saisir truc :
Saisir truc :
...
Dernière modification par guguscat (Le 01/12/2007, à 21:14)
Un problème non résolu ? Indiquez le en insultant les gens qui tentent de vous aider.
Hors ligne
#5 Le 02/12/2007, à 00:52
- AuraHxC
Re : [résolu] Saisie sécurisée en C
Il me semble que pour faire une saisie sécurisé, le bon plan serait déjà de laisser scanf
http://c.developpez.com/faq/?page=clavier_ecran#SCREEN_scanf_fgets
Hors ligne
#6 Le 02/12/2007, à 14:01
- guguscat
Re : [résolu] Saisie sécurisée en C
Ce n'est pas une mauvaise idée mais le truc c'est que là j'ai pas le choix en fait.
Un problème non résolu ? Indiquez le en insultant les gens qui tentent de vous aider.
Hors ligne
#7 Le 02/12/2007, à 18:45
- $Gaël$
Re : [résolu] Saisie sécurisée en C
peut-être essayer de faire un flush du clavier pour vider le tampon d'écriture
Ubuntu is an ancient african word meaning : "I can't configure Debian".
Hors ligne
#8 Le 02/12/2007, à 19:29
- guguscat
Re : [résolu] Saisie sécurisée en C
C'est pas ce qui est fait déjà ?
fflush(stdin)
Un problème non résolu ? Indiquez le en insultant les gens qui tentent de vous aider.
Hors ligne
#9 Le 02/12/2007, à 20:18
- tructu
Re : [résolu] Saisie sécurisée en C
le mieux c'est de faire
while ((c = getchar()) != '\n' && c != EOF);
pour vider ton buffer !
(cf :http://c.developpez.com/faq/?page=clavier_ecran )
#include <stdio.h>
#include <stdlib.h>
int main()
{
long truc;
int saisie,c;
do
{
printf("\nSaisir truc : ");
saisie=scanf("%ld", &truc);
while ((c = getchar()) != '\n' && c != EOF);
} while(saisie!=1);
printf("\nTruc = %ld", truc);
return 0;
}
#10 Le 02/12/2007, à 20:23
- $Gaël$
Re : [résolu] Saisie sécurisée en C
C'est pas ce qui est fait déjà ?
fflush(stdin)
Oups, désolé j'ai regardé le code trop rapidement
Ubuntu is an ancient african word meaning : "I can't configure Debian".
Hors ligne
#11 Le 02/12/2007, à 20:44
- guguscat
Re : [résolu] Saisie sécurisée en C
le mieux c'est de faire
while ((c = getchar()) != '\n' && c != EOF);
pour vider ton buffer !
Merci à tous ça marche.
Un problème non résolu ? Indiquez le en insultant les gens qui tentent de vous aider.
Hors ligne
#12 Le 02/12/2007, à 21:24
- Watchwolf
Re : [résolu] Saisie sécurisée en C
scanf est une fonction à abandonner, elle ne sert à rien, elle renvoie un buffer tout bordélique
utilise fgets plus des fonction de conversion comme aoit, atof, sprintf ou sscanf.
Hors ligne
#13 Le 02/12/2007, à 22:55
- AuraHxC
Re : [résolu] Saisie sécurisée en C
+1 Watchwolf
Hors ligne
#14 Le 03/12/2007, à 20:31
- guguscat
Re : [résolu] Saisie sécurisée en C
scanf est une fonction à abandonner, elle ne sert à rien, elle renvoie un buffer tout bordélique hmm
utilise fgets plus des fonction de conversion comme aoit, atof, sprintf ou sscanf.
Je ne peux que être que d'accord sauf que dans mon contexte je n'ai pas trop le choix d'utiliser d'autres fonctions que scanf. Alors je prends note et dès que j'aurais le choix je repenserai à tout ce que vous m'avez dit.
Un problème non résolu ? Indiquez le en insultant les gens qui tentent de vous aider.
Hors ligne
#15 Le 04/12/2007, à 01:16
- AuraHxC
Re : [résolu] Saisie sécurisée en C
C'est quoi la contrainte pour que tu sois obligé d'utiliser scanf ??
Tu est étudiant peut être et ton prof ta demandé d'utiliser avec scanf ??
Hors ligne
#16 Le 04/12/2007, à 09:01
- Marabout
Re : [résolu] Saisie sécurisée en C
Salut,
Normalement fflush ne doit être utilisé que sur les tampons de sortie et pas sur ceux d'entrée. le comportement de fflush(stdin) n'est pas normalise, sur certains compilateurs le resultat est bien de vider le tampon, mais sur d'autres ca ne fonctionnera pas. Donc je te conseille de ne pas utiliser fflush(stdin).
Hors ligne
#17 Le 04/12/2007, à 22:02
- _SamSoft_
Re : [résolu] Saisie sécurisée en C
Je reprend le message du dessus en plus clair :
fflush(stdout); après un printf (ou équivalent : fprintf...)
fflush(stdin); comportement indéterminé : à oublier
fclean(var, stdin); ca c'est correct par contre il faut soit même implémenter fclean elle n'est pas dans les headers standards.
fgets : conseillée car sécurisée (du moins pour ceux qui ne maà®trisent pas scanf)
Voilà
Bonne prog et bonne nuit !
PS: Voilà en cadeau : (OUAH ! )
void fclean (char *s_buffer, FILE * stream)
{
if (s_buffer != NULL && stream != NULL)
{
char *pc = strchr (s_buffer, '\n');
if (pc != NULL) /* La saisie n'a pas ete tronquee */
{
/* On remplace '\n' par le caractere nul '\0' */
*pc = 0;
}
else
{
/* La saisie a ete tronquee, on purge le flux d'entree */
int c;
while ((c = fgetc (stream)) != '\n' && c != EOF)
{
}
}
}
}
if(!physics)
/* nothing */
else
/* everything */
Hors ligne
#18 Le 05/12/2007, à 01:05
- guguscat
Re : [résolu] Saisie sécurisée en C
Tu est étudiant peut être et ton prof ta demandé d'utiliser avec scanf ??
oui c'est ça
le comportement de fflush(stdin) n'est pas normalise
Un truc qui est bizar quand même c'est que j'utilise gcc chez moi et à l'école.
L'autre jour à l'école avec un fflsuh(stdin) ça me faisait une boucle infinie, chez moi idem, et je recompil aujourd'hui à l'école et ça marchait !!
Moi je dis vive la vie quand même.
Un problème non résolu ? Indiquez le en insultant les gens qui tentent de vous aider.
Hors ligne
#19 Le 05/12/2007, à 09:16
- _SamSoft_
Re : [résolu] Saisie sécurisée en C
Oui fflush(stdin); c'est indéterminé des fois ca marche chez certains d'autres pas le lendemain, ca change donc fclean(var, stdin); et fflush(stdout);
if(!physics)
/* nothing */
else
/* everything */
Hors ligne
#20 Le 05/12/2007, à 17:35
- AuraHxC
Re : [résolu] Saisie sécurisée en C
Tu est étudiant peut être et ton prof ta demandé d'utiliser avec scanf ??
oui c'est ça
Ah ben bravo
Et tu crois que ça va le tuer que tu utilise autre chose que scanf
Hors ligne
#21 Le 06/12/2007, à 23:40
- guguscat
Re : [résolu] Saisie sécurisée en C
Oui j'en ai peur....
Déjà que il a eu du mal quand j'initialisais ma variable en même tps que la délarer.
Un problème non résolu ? Indiquez le en insultant les gens qui tentent de vous aider.
Hors ligne