Limite de nombres saisis par un utilisateur

Fermé
assaid20 - 24 sept. 2013 à 10:13
[Dal] Messages postés 6184 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 29 mai 2024 - 30 sept. 2013 à 14:26
Bonjour,

Je suis ASSAID étudiant en 1ère année d'ingénierie informatique. J'ai un peu de souci par rapport à un programme c que je suis entrain d'implémenter. Au fait le programme c'est de faire stocké les données entrées par l'utilisateur dans un répertoire .txt .
A ce niveau il n' y a pas de problème je me suis débrouillé à le faire, mais ce qui me reste à faire c'est de demander à l'utilisateur d'entrer un numéro (un contact par exemple) ne dépassant pas 8 chiffres.

Cordialement

10 réponses

nar6du14 Messages postés 459 Date d'inscription dimanche 27 décembre 2009 Statut Membre Dernière intervention 7 décembre 2013 64
Modifié par nar6du14 le 24/09/2013 à 12:31
int n = count = 1;
int tab[8] = {0};
do
{
scanf("%d", &n);
tab[count] = n;
count++;
if( count == 8)printf("\ limite de caractères atteinte!!! \n");
}while(count<9);
0
assaid20 Messages postés 2 Date d'inscription vendredi 20 septembre 2013 Statut Membre Dernière intervention 30 septembre 2013
24 sept. 2013 à 12:28
D'abord merci beaucoup de m'avoir répondu, je vais vous faire part après avoir essayé le programme, une fois de plus merci!!!
0
juliencolin54 Messages postés 217 Date d'inscription dimanche 22 juillet 2012 Statut Membre Dernière intervention 1 octobre 2013 55
24 sept. 2013 à 13:01
Bonjour,

Désolé pour cette remarque mais, déjà un scanf() c'est pas super propre, mais alors une boucle de scanf()... C'est folie !
0
nar6du14 Messages postés 459 Date d'inscription dimanche 27 décembre 2009 Statut Membre Dernière intervention 7 décembre 2013 64
24 sept. 2013 à 17:08
pas forcément, la zone mémoire utilisée est toujours la mème d'autre part, la boucle n'est pas infinie vu qu'elle dépende de la variable count!

mais, bien évidemment il faut des notions sur les pointeurs pour bien maitriser ceci
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
nar6du14 Messages postés 459 Date d'inscription dimanche 27 décembre 2009 Statut Membre Dernière intervention 7 décembre 2013 64
Modifié par nar6du14 le 24/09/2013 à 18:16
j'avoue que le getchar n'est pas mal!!!

on peut faire ceci:

void entrer_caracteres( char* tab)
{
int count = 0;
do
{
tab[count] = ( char )getchar();
count++;
if( count == 9)
{
printf("\n limite de caractères atteinte!!! \n");
}
}while(count<9);
}

tu dois passer à cette fonction une tableau de 9 caractères comme ce qui suit!!!

char tab[9] = {"\n"}; //9 à cause du dernier élément qui sera "\n"
0
juliencolin54 Messages postés 217 Date d'inscription dimanche 22 juillet 2012 Statut Membre Dernière intervention 1 octobre 2013 55
25 sept. 2013 à 08:44
Mais de tout de façon une boucle où l'utilisateur doit rentrer les chiffres un par un c'est moche et pas pratique du tout.

De plus tu dis :
"mais, bien évidemment il faut des notions sur les pointeurs pour bien maitriser ceci".
Est-ce que c'est une blague ? Tu as l'air de penser que ta boucle avec les
printf()
est safe.... Mais en fait, non !

Renseigne toi justement sur les capacités de
printf()
avant de donner du code comme celui ci.

Cdlt,
0
[Dal] Messages postés 6184 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 29 mai 2024 1 087
25 sept. 2013 à 15:52
S'agissant de la proposition getchar, pour la saisie de caractères, comme getchar travaille sur un flux, la boucle va traiter les caractères tant qu'il en trouve dans stdin et non pas demander les chiffres un par un (ce n'est pas getch de conio.h, non standard, mais le getchar de stdio.h). Il suffit de tester si le caractère '\n' se trouve dans le flux, pour qu'elle remplisse ton office et teste (et gère) la fin de ligne, en même temps que le nombre maximal de caractères capturés, en tronquant le reste.

cela dit, fgets ou scanf me semblent plus appropriés (pas gets, qui ne permet pas de spécifier la taille du tampon, et qui a été d'ailleurs retirée du C11).


Dal
0
[Dal] Messages postés 6184 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 29 mai 2024 1 087
Modifié par [Dal] le 26/09/2013 à 11:50
Salut assaid20,

A la réflexion, pour bien faire les choses, je crois que tu dois en fait prendre en compte deux problèmes :

- tu dois obtenir une saisie de 8 chiffres
- ces chiffres correspondent à un numéro de téléphone

Lorsque les utilisateurs saisissent un numéro de téléphone, il est fréquent qu'il ajoutent des espaces entre les numéros, des points, tirets, slashes, parenthèses, ou d'autres caractères. Ils ne considèrent pas pour autant que leur saisie est fausse, s'ils ajoutent ces caractères.

Tu devrais donc prendre en compte cela et le fait que cela va augmenter la taille de la chaîne saisie, et donc prévoir large en taille. Ensuite, il te faut une fonction pour filtrer les caractères autorisés saisis, vérifier que la chaine comporte 8 chiffres, pas d'autres caractères non autorisés, et retourner la chaîne filtrée.

Comme c'est un numéro de téléphone, tu devrais le conserver sous forme de chaîne. Cela n'a pas trop de sens de le transformer en entier. En plus, cela te simplifiera la vie au moment de l'écrire dans ton fichier texte.

Si tu as des difficultés à utiliser fgets ou scanf pour limiter ta saisie, dis le. Il y a des subtilités à prendre en compte.

fgets, par exemple, va éventuellement capturer le '\n' que tu ne veux certainement pas dans ta chaîne, et qu'il te faudra retirer.

quant à scanf, utilisé avec les bons délimitateurs, il n'inclura pas '\n' dans la capture, mais '\n' restera alors dans le flux non consommé, et il te faudra purger le flux stdin pour qu'il ne soit pas envoyé lors d'une prochaine capture du flux stdin.

Si tu sais tout cela, ce ne sont que des rappels. Si c'est pas clair pour toi, on peut te donner des exemples.


Dal
0
assaid20 Messages postés 2 Date d'inscription vendredi 20 septembre 2013 Statut Membre Dernière intervention 30 septembre 2013
30 sept. 2013 à 09:41
J'ai bien compris mais je crois que je n'y arriverais pas, j'ai tout essayé. Votre aide sera la bienvenue. Merci
0
[Dal] Messages postés 6184 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 29 mai 2024 1 087
Modifié par [Dal] le 30/09/2013 à 14:30
OK, voilà une charpente sur laquelle tu peux te baser, utilisant fgets :

#include <stdio.h>
#include <ctype.h> /* on aura besoin de isdigit */
#include <string.h> /* on aura besoin de strcpy */

/**
* validate_phone - détermine si numéro valide
*
* filtre la chaîne st en retirant les caractères
* autorisés, et vérifie qu'elle est composée que
* de 8 chiffres
*
* st: pointeur vers chaîne à valider
* retourne :
* 0 (faux) si la chaîne est non valide
* 1 si la chaîne passe les tests
* la chaîne validée et expurgée des caractères
* autorisés est alors disponible à l'adresse
* pointée par st
*/
int validate_phone(char * st)
{
/* a toi de jouer ici */
}

int main(void)
{
char st[50] = { '\0' };
char c;
char * p;

printf("Veuillez saisir un numéro de "
"téléphone à 8 chiffres :\n");

if (fgets(st, sizeof(st), stdin) != NULL) /* fgets permet de limiter
* la taille de la saisie
* prise en compte */
{
if ((p = strchr(st, '\n')) != NULL) /* si la saisie, y compris \0, */
*p = '\0'; /* est moins longue que la
* taille du tampon alloué, \n
* sera aussi capturé, et il
* faut le retirer */

else /* si la saisie, y compris \0,
* est exactement de la taille
* maximale ou supérieure, \n et
* le reste éventuel de stdin ne
* sont pas capturés, mais sont
* toujours dans le flux stdin,
* qu'il est préférable de vider */
while ((c = getchar()) != '\n' && c != EOF)
/* façon standard de purger stdin */;

printf("vous avez tapé : \"%s\", veuillez presser entrer\n", st);
getchar(); /* une "pause" : celle-ci fonctionne si stdin est vide */

if (validate_phone(st)) /* à toi de jouer ici, en faisant
* ta fonction de validation */
{
printf("C'est un numéro de téléphone valide, "
"composé des 8 chiffres suivants : %s\n", st);
}
else
{
printf("Ce n'est pas un numéro de "
"téléphone valide à 8 chiffres\n");
}
} else
{
printf("Erreur de saisie\n"); /* ne devrait jamais arriver ici */
}

return 0;
}

Dans ta fonction, tu pourrais par exemple énumérer les caractères contenus dans st un par un en vérifiant s'ils sont acceptables ou pas (espaces, points, tirets,...) avec un switch / case, et extraire les caractères correspondant à des chiffres en les testant avec isdigit, tout en contrôlant qu'il n'y a que des chiffres et pas autre chose.

Il est plus simple d'appliquer un simple strtol sur st, comme le propose fiddy, mais, tu perds alors en fonctionnalité en ne gérant pas le fait que, pour un utilisateur "01-23-45-67" peut être une saisie correcte d'un numéro de téléphone.


Dal
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 836
26 sept. 2013 à 23:18
Pour le nombre à 8 chiffres, tu peux utiliser le couple fgets / strtol.
C'est amha, le plus propre.
Je te laisse faire à titre d'exercice. N'hésite pas, si tu bloques.
0
juliencolin54 Messages postés 217 Date d'inscription dimanche 22 juillet 2012 Statut Membre Dernière intervention 1 octobre 2013 55
24 sept. 2013 à 13:10
Bonjour,

Si tu tiens absolument à utiliser scanf(), (je ne t'encourage pas) alors utilises ce en quoi il est puissant, les chaînes formatées.

Par exemple avec des "%8d" ou "%8s" sur lequel tu fais une conversion en int après vérification.

Sincèrement, il vaut mieux utiliser gets()/puts() lorsqu'on ne maitrise pas encore parfaitement les pointeurs ainsi que les capacités des fonctions *printf et *scanf.

Si tu t'entêtes à quand même rester sur un scanf(), ma documentation favorite est celle ci : https://xrenault.developpez.com/tutoriels/c/scanf/
Tu devrais y trouver ton bonheur.

Cordialement.
-1
[Dal] Messages postés 6184 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 29 mai 2024 1 087
26 sept. 2013 à 09:59
Tu dois vouloir dire fgets, car gets est le meilleur moyen d'obtenir un débordement de mémoire.

http://c-faq.com/stdio/getsvsfgets.html


Dal
0
juliencolin54 Messages postés 217 Date d'inscription dimanche 22 juillet 2012 Statut Membre Dernière intervention 1 octobre 2013 55
26 sept. 2013 à 10:04
Ah, non je voulais bien dire gets()...

J'étais pas au courant, merci de l'info ! :)
Mais, personnellement j'utilise getline().
0
[Dal] Messages postés 6184 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 29 mai 2024 1 087
26 sept. 2013 à 11:04
getline(), je suppose que c'est mieux, pourvu que l'on fasse du C++ ;-)
0
juliencolin54 Messages postés 217 Date d'inscription dimanche 22 juillet 2012 Statut Membre Dernière intervention 1 octobre 2013 55
26 sept. 2013 à 11:13
Pourquoi du C++ ?
Est-ce que tu dis ça car tu penses qu'il n'existe pas en C ? Si c'est le cas, détrompes toi :)
0
[Dal] Messages postés 6184 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 29 mai 2024 1 087
26 sept. 2013 à 11:47
Elle existe en C++ standard sous cette forme : http://www.cplusplus.com/reference/string/string/getline/ (depuis C++98)

Mais, sauf erreur, elle n'existe pas en C standard. C'est une extension GNU au C.

La GNU C Library contient une implémentation C de cette fonction non standard
ssize_t getline (char **lineptr, size_t *n, FILE *stream)
, qui a été créée pour éviter les complications dues au recours aux fonctions standard du C pour faire quelque chose d'aussi habituel que lire une ligne de texte dont on ne connaît pas nécessairement la taille à l'avance.

http://www.gnu.org/software/libc/manual/html_node/Line-Input.html

Mais ce n'est pas portable, à moins que tu me parles d'un standard que je ne connais pas, auquel cas, je veux bien que tu m'indiques tes références :-)


Dal
0