|
Publicité ' | ||||||||||||||||||||||||
|
|
#1 |
|
Membre à l'essai
![]() Rulx Philome AlexisÉtudiant Inscription : janvier 2013 Messages : 19 ![]() |
Salut à tous!!!! Je veux entrer une fonctionnalité dans un programme qui concerne la saisie. En programmant, si la saisie n'est pas sécurisée on risque d'obtenir de nombreux bugs ou de résultats vraiment obsolètes. Mon problème c'est comment s'assurer que l'utilisateur entrera un chiffre quand on demande un chiffre ou un caractère quand on demande un caractère. Si il entre un caractère en lieu et place d'un chiffre cela ne causera pas de problème vu que ce caractère sera converti en un nombre quelconque dépendemment de l'ordinateur. Donc ma question, comment s'assurer que même quand il saisie une lettre le programme redemendera d'entrer le bon éléments. On ne va quand même pas lister tous les lettres de l'alphabets (majuscules et minuscules ) ![]() dans une boucle do{}while(); pour empecher cela.C'est beaucoup!!!!!!! ![]() Je suis sure qu'il y a une facon plus simple de faire Ainsi, a-t-il été exposé mon problème. Merci déjà de me preter main forte dans ma recherche ![]() ![]()
|
|
00
|
|
|
#2 |
![]() ![]() Chercheur d'emploi Inscription : septembre 2007 Messages : 4 614 ![]() |
Bonjour,
Soit tu utilises des bibliothèques spécialisées dans les masques de saisie, soit tu t'arranges au préalable pour recevoir directement les caractères saisis par l'utilisateur (les terminaux UNIX les bufferisent par défaut et les envoient sur un retour à la ligne) et tu contrôles la validité du caractère. Pour faire cette validation, tu n'es pas forcément obligé de tester une à une les valeurs légitimes. Les codes des caractères ASCII sont faits pour être consécutifs pour la plupart. Par exemple, si tu veux vérifier que le caractère contenu dans « c » est un chiffre entre 0 et 9, tu peux écrire : |
|
|
00
|
|
|
#3 |
![]() ![]() Patrick GonordEnseignant Chercheur Inscription : juin 2005 Messages : 5 434 ![]() |
Il existe aussi des fonctions standard de classification des caractères : isdigit(), isalpha(),... (cf <ctype.h>)
__________________
Publication : Concepts en C Mon avatar : Glenn Gould -------------------------------------------------------------------------- Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !
|
|
|
50
|
|
|
#4 |
|
Membre Expert
![]() Ingénieur développement logiciels Inscription : octobre 2008 Messages : 1 482 ![]() |
Il faut faire attention aussi au fait qu'une entrée numérique valide peut comporter d'autres caractères que des chiffres : moins, plus, virgule et/ou point, éventuellement espaces, e ou E pour un flottant...
Inversement, une entrée qui ne comporte que des chiffres ne forme pas forcément un entier valide pour ton programme puisque tu peux avoir un débordement. En pratique plutôt que de valider chaque caractère indépendamment des autres, il est souvent plus simple et plus sûr de valider l'entrée complète. Par exemple si tu attends un entier, tu vas probablement utiliser strtol() pour faire la conversion, et si elle est utilisée correctement cette fonction donnera une erreur si l'entrée ne représente pas un entier. Attention d'ailleurs, certaines fonctions de comparaison (atoi() par exemple) ne permettent pas toujours de gérer les erreurs de façon satisfaisante (atoi() par exemple revoie 0 en cas d'erreur, mais aussi si l'entrée représente le nombre 0). |
|
|
30
|
|
|
#5 | |
|
Membre à l'essai
![]() Rulx Philome AlexisÉtudiant Inscription : janvier 2013 Messages : 19 ![]() |
Citation:
La je besoin que tu me parles un peu plus sur les fonctions tel atoi(),atof(),atol() Mon probleme avec c'est que je ne sais pas exactement dans quell bibliotheque elles se trouvent |
|
|
00
|
|
|
#6 | |
|
Membre éclairé
![]() ![]() Inscription : août 2007 Messages : 174 ![]() |
Citation:
http://man.developpez.com/man3/atoi.3.php Encore une fois "strtol" est plus sûr... |
|
|
|
30
|
|
|
#7 |
|
Expert Confirmé Sénior
![]() ![]() Ingénieur systèmes embarqués Inscription : juin 2009 Messages : 1 703 ![]() |
Si on parle de sécurité des saisies, il est évident qu'on banni les fonctions de la famille d'atoi() ! +1 pour pythéas !
Je redonne aussi un lien qu'on donne tout le temps ici : http://emmanuel-delahaye.developpez....ees-solides-c/
__________________
Si Code::Blocks vous dit undefined reference to 'socket@12', cela signifie que vous avez un problème d'édition des liens. Allez dans Projects / Build Options / Linker Settings / Add et renseigner ici les .a qui vont bien. Exemple pour les sockets : C:\Program Files\CodeBlocks\MinGW\lib\libws2_32.a Pour les adeptes du langage SMS, allez ici et ramenez la traduction française ^^ Pour vos problèmes d'embarqué, utilisez le forum dédié ! |
|
10
|
|
|
#8 | |
|
Membre à l'essai
![]() Rulx Philome AlexisÉtudiant Inscription : janvier 2013 Messages : 19 ![]() |
Citation:
Pytheas Merci piur tes conseils Je voudrais juste que tu me donnes le prototype de la fonction strtol() Car en compilant on me doit qu'il me manque un argument... |
|
|
00
|
|
|
#9 |
|
Membre éclairé
![]() ![]() Inscription : août 2007 Messages : 174 ![]() |
http://www.cplusplus.com/reference/cstdlib/strtol/
Bon c'est un site c++ mais ça change pas grand chose. Sinon c'est vraiment pas une info difficile à trouver |
|
|
00
|
|
|
#10 | |
![]() ![]() Chercheur d'emploi Inscription : septembre 2007 Messages : 4 614 ![]() |
Citation:
http://man.developpez.com/man3/strtol.3.php |
|
|
|
00
|
|
|
#11 | ||
|
Expert Confirmé Sénior
![]() ![]() Frédéric Ingénieur développement logiciels Inscription : février 2006 Messages : 3 495 ![]() |
Bonjour
Un peu de retard mais j'étais absent. +1 pour l'intervention de bktero. Moi, si je veux faire une saisie vérifiée, j'utilise fgets() pour que le buffer clavier soit bien entièrement récupéré puis ensuite sscanf() pour extraire de la chaine saisie l'élément qui m'intéresse. Et chose avantageuse, sscanf() renvoie le nb d'éléments correctement extraits... Exemple Code c :
__________________
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche. Tout ce qu'un individu reçoit sans rien faire pour l'obtenir, un autre individu a dû travailler pour le produire sans en tirer profit. Tout Pouvoir ne peut distribuer aux uns que ce qu'il a préalablement confisqué à d'autres car on n'accroît pas les biens en les divisant. Quand la moitié d'un peuple croit qu'il ne sert à rien de faire des efforts car l'autre moitié les fera pour elle, et quand cette dernière moitié se dit qu'il ne sert à rien d'en faire car ils bénéficieront à d'autres, cela s'appelle le déclin et la fin d'une nation. Dr. Adrian Rogers, 1931 |
||
|
|
10
|
|
|
#12 | ||||
|
Membre éclairé
![]() Alex VEtudiant administrateur systèmes et réseaux Inscription : octobre 2007 Messages : 609 ![]() |
Salut,
Voici une fonction de saisie "sécurisée". Code :
Code :
__________________
UNE REPONSE UTILE : &|| UN PROBLEME RESOLU :
|
||||
|
|
01
|
|
|
#13 | |||||
|
Membre à l'essai
![]() Rulx Philome AlexisÉtudiant Inscription : janvier 2013 Messages : 19 ![]() |
Citation:
Suite au commentaire de blackwall_37 j'ai cherché à mieux comprendre l'utilisation du pointeur dans bon nombre des fonction. Ces pointeurs sont de types CHAR. ils sont la pour accéder à des adresses. Leurs arguments effectifs n'auront pas le charactère & puisque un tableau de charactère est un pointeur. Il me semble que j'ai un peu de lacune en ce qui concerne les pointeurs. Je n'arrive pas à bien saisir le syntaxe et aussi la théorie qui se cache derrière. Jusque là mon problème n'a pas été présenté parfaitement mais je pense que vous pourrez me donner un brin d'explication et aussi des références pour que je puisse me tirer de cette mauvaise passe... |
|||||
|
00
|
|
|
#14 | ||||||||
|
Expert Confirmé
![]() Pierre Ingénieur développement logiciels Inscription : juin 2007 Messages : 1 185 ![]() |
Bonjour!
Pour faire simple avec les pointeurs, il faut partir de la notion de mémoire. à la base, un ordinateur, c'est des atomes mémoires (les bits), et des transistors pour les modifier. Une variable est deux choses:
Cette adresse est simplement le numéro de la case mémoire, en commencant gentillement par 0, et allant jusqu'à … ca dépend de la taille des adresses (32 bits ou 64 bits). Chaque programme reçoit une simulation de l'ensemble de la RAM, c'est à dire que, chaque programme peut utiliser chaque adresse de 0 à ADRESSE_MAX. Si tu écris int entier = 32;, le compilateur génère en théorie: Code :
Un int fait plusieurs bytes, donc occupe plusieurs cases successives, mais je laisse ce détail pour l'instant. Un pointeur, c'est juste une variable normale, dont le type est "adresse mémoire, d'un type donné". Le code int *pointeur; définit une variable, nommée pointeur, et dont le type est pointeur d'entier. Elle peut donc recevoir l'adresse d'une variable de type int. Personnellement, j'aime dire que int *pointeur; déclare "ce que pointerait la variable pointeur est un entier". Pourquoi? parce que de même que int a, b; définit deux "int" (a et b), int * pointeur, alpha; définit "ce que pointerait pointeur" et alpha comme deux int. Une question doit te venir en tête: comment donner une valeur à un pointeur? C'est le rôle de l'opérateur d'adressage, & (l'opérateur unaire…) Si alpha est une variable, alors &alpha est son adresse. Tu peux donc écrire: Code :
Code :
Pour le passage de paramètres d'une fonction, les valeurs de paramètres sont copiés. Par exemple, ce programme affichera "7 2": Code :
Pour les tableaux, c'est autre façon de voire la chose. Supposons int tableau[3] = {1, 2, 3};. Alors tableau est un bloc mémoire contigu, dont la taille est 3*sizeof (int). Le C permet d'utiliser tableau comme un pointeur vers le premier élément de ce tableau. Ceci à deux effets: *tableau et tableau[0] sont la même variable, le premier int du bloc désigné par tableau. plus fort, il est possible d'ajouter un décallage (entier) à un pointeur. (pointeur+2) est une expression dont la valeur est l'adresse situé 2 <type pointé par pointeur> plus loin que celle contenu dans pointeur. C'est une adresse du même type que celle contenu dans pointeur, et utilisable de la même manière: *(pointeur+2) = 2;Attention, énorme soucis: pour avoir le droit de déréférencer cette adresse, il faut qu'elle appartienne au programme (sous peine de "segmentation fault"). C'est vrai pour tout pointeur, mais l'arithmétique de pointeur est l'art de se tromper facilement… Le point commun dans cette histoire? *(tableau+1), *(1+tableau), tableau[1], 1[tableau] sont quatre noms de la même variables, de même que *(&(tableau[2]) -1) L'autre lien, c'est la notion de distance mémoire: [codeinline]ptrdiff_t distance = &(tableau[2]) - &(tableau);(codeinline] déclare une variable dont la valeur est la différence entre les deux adresses, exprimée comme multiple de sizeof(int). La différence de deux pointeurs (de même type), est la taille du tableau allant de l'un à l'autre. J'espère t'avoir apporté quelques éclaircissement. Pour plus d'informations, lit donc la faq. Bonne journée, et félicitation d'avoir lu jusque ici!
__________________
Mes principes de bases du codeur qui veut pouvoir dormir:
|
||||||||
|
11
|
|
|
#15 | |
|
Membre émérite
![]() ![]() |
Bonjour,
Citation:
Bonne journée !
__________________
Récursivité en C : épidémie ou hérésie ? "Pour être un saint dans l'Église de l'Emacs, il faut vivre une vie pure. Il faut se passer de tout logiciel propriétaire. Heureusement, être célibataire n'est pas obligé. C'est donc bien mieux que les autres églises" - Richard Stallman |
|
|
12
|
|
|
#16 |
|
Membre éclairé
![]() Alex VEtudiant administrateur systèmes et réseaux Inscription : octobre 2007 Messages : 609 ![]() |
? "sécurisée"
__________________
UNE REPONSE UTILE : &|| UN PROBLEME RESOLU :
|
|
|
00
|
|
|
#17 |
|
Membre émérite
![]() ![]() |
Puisque tu sembles considérer mon précédent message comme étant faux (vote contre implique), comment justifies-tu l'utilisation de ce comportement indéterminé ?
fflush (stdin) n'est pas dangereux en soi ; il s'agit simplement d'une habitude erronée. Aussi dénonçais-je pas tant l'emploi de « "sécurisée" », que l'incohérence de ton code source.
__________________
Récursivité en C : épidémie ou hérésie ? "Pour être un saint dans l'Église de l'Emacs, il faut vivre une vie pure. Il faut se passer de tout logiciel propriétaire. Heureusement, être célibataire n'est pas obligé. C'est donc bien mieux que les autres églises" - Richard Stallman |
|
21
|
|
|
#18 |
![]() ![]() Chercheur d'emploi Inscription : septembre 2007 Messages : 4 614 ![]() |
|
|
|
30
|
|
|
#19 | |
|
Membre éclairé
![]() Alex VEtudiant administrateur systèmes et réseaux Inscription : octobre 2007 Messages : 609 ![]() |
Citation:
Je ne dis pas que ce que vous dites est faux. Surtout moi, je ne me permettrais pas.
__________________
UNE REPONSE UTILE : &|| UN PROBLEME RESOLU :
|
|
|
|
00
|
|
|
#20 |
|
Expert Confirmé Sénior
![]() ![]() Ingénieur systèmes embarqués Inscription : juin 2009 Messages : 1 703 ![]() |
Ce que veulent dire Kirilenko et Obsidian, c'est que tu ne peux pas faire un code sécurisé (par nature fiable) avec des opérations au comportement indéterminé (qui sont pas nature non fiables), tel que fflush(stdin).
__________________
Si Code::Blocks vous dit undefined reference to 'socket@12', cela signifie que vous avez un problème d'édition des liens. Allez dans Projects / Build Options / Linker Settings / Add et renseigner ici les .a qui vont bien. Exemple pour les sockets : C:\Program Files\CodeBlocks\MinGW\lib\libws2_32.a Pour les adeptes du langage SMS, allez ici et ramenez la traduction française ^^ Pour vos problèmes d'embarqué, utilisez le forum dédié ! |
|
30
|
Copyright © 2000-2013 - www.developpez.com