[RESOLU][C][uber noob inside]saisie de lettre là ou j'attends des chiffres

ami cafzoniens bonjour!
le wack a craquer, il est passe du coté obscur …
à la lecture d’un topic “apprendre à programmer” je me suis dis qu’après tout cela ne me ferai pas de mal de m’y mettre aussi
je me suis donc mis en quete de tuto pour les tanches et j’en ai trouver un sympa (sitedu zero.com)
alors je le précise, j’ai trois quatre heures de pratique derriere moi( ouais carrément) et un petit truc sympa à programmer (un 'tit jeu de + ou -)
j’ai un peu (beaucoup) remanier le code et j’ai rajouter des options(niveau de difficulté, continue,compteur de coup,et message d’erreur et même un game over!)
alors, c’est méchament basic, sans doute codé comme un porc mais rien de ce que j’ai rajouté n’était documenté, et en plus ça marche:
d’ailleurs voilà le bestiau:

[code]#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/jeu de +ou-
creer par moi meme, d’apres M@teo21 du site du zero
ceci est la version 0.3
/
int main(int argc, char *argv[])
{
const long MIN=1;//on instaure une constante mini
long MAX=100;// et une variable maxi(100 de base)
long nombreMystere;//ça c’est notre variable mystere
long compteur=0;//on initialise le compteur
int continuer=1;//la c’est le continue
long saisi=0;//le chiffre que le joueur saisira
long difficulte=1;//on fixe le niveau de difficulte de depart

do//debut du jeu
{
//selection du niveau de difficulté
do
{//debut de la boucle
printf(“choisissez votre niveau de difficulte\n\n”);
printf(“1.facile\n”);
printf(“2.moyen\n”);
printf(“3.dur\n\n\t”);
scanf("%ld",&difficulte);//c’est ici qu’on modifie le niveau
if (difficulte==1)//choix1
{
MAX=10;//on fixe la limite à 10
}
else if (difficulte==2)//choix 2
{
MAX=100;//on fixe la limite à 100
}
else if (difficulte==3)//choix 3
{
MAX=1000;//on fixe la limite à 1000
}
else //mauvais choix
{
printf (“1, 2, ou 3, c’est pourtant pas dur!\n”);
}
}//fin de la boucle
while (difficulte>3);/si le joueur rentre une valeur superieure à 3
on recommence la boucle
/
//fin selection du niveau de difficultés

//et on balance un nombre aleatoire   

srand(time(NULL));
nombreMystere = (rand() % (MAX - MIN + 1)) + MIN;
//voilà ça c’est fait…
do
{
compteur++;//on commence par incrementer le compteur de coups de 1

printf(“quel est le nombre mystere?\t”);// on pose la question
scanf("%ld",&saisi);//le joueur repond
while (saisi>MAX)//si le joueur rentre un nombre hors borne
{
printf(“le nombre doit etre entre 1 et %ld\n”,MAX);
scanf("%ld",&saisi);
}//on boucle tant que le joueur se trompe

// le jeu se deroule
if (saisi<nombreMystere)
{
printf(“c’est plus!\n\n”);
}
else if (saisi>nombreMystere)
{
printf(“c’est moins!\n\n”);
}
else
{
printf(“bravo le nombre mystere est %ld\nvous l’avez trouve en %ld coups\n\n”,nombreMystere,compteur);
}
if (compteur==15)
{
printf (“perdu,plus de tentatives possibles\n\tla solution etait %ld\n”,nombreMystere);
saisi=nombreMystere;
}
}
//jusqu’a ce que le joueur ai trouvé
while (saisi!=nombreMystere);

//on lui propose alors de continuer ou pas(voir la fin du code)
printf(“souhaitez vous continuez?\n\n”);
printf(“1. continuez\n”);
printf(“0. arretez,stop!!!\n\t”);
scanf("%ld",&continuer);
//s’il choisi de continuer on reinitilise le nombre mystere
srand(time(NULL));
nombreMystere = (rand() % (MAX - MIN + 1)) + MIN;
//et le compeur de coups
compteur=0;
}
while (continuer!=0);// le jeu boucle tant que le joueur ne met pas le continue à 0

system(“PAUSE”);
return 0;
}[/code]

le pourquoi du topic?
oui, j’ai failli oublier, en fait j’ai fait tester le bouzin
et le premier truc que mon “testeur-beta” à fait, c’est de rentrer des lettres au lieu de chiffres
et tout c’est mis à boucler à l’infini.
j’ai cru comprendre que le scanf renvoyait à une adresse mémoire, et que saisir des lettres dans la mémoire c’est le mal( elle comprend que les chiffres mémére)
aussi je souhaiterai:
soit pouvoir renvoyer un message d’erreur au joueur lui priant de mettre des chiffres (comme j’ai fait pour les chiffres hors bornes)
soit carrément empecher la saisie de lettre.
soit enfin faire comprendre à mon programme qu’il ne doit pas s’enerver pour si peux, et que un jour quand je serai bon je lui apprendrai à lire.

j’ai chercher sur le site en question,j’ai même poster sur leur forum, mais j’ai l’impression que seuls des beotiens comme moi tente de répondre.
et, n’ayant pas le vocabulaire nécésaire, google a du mal à etre mon ami.

quelqu’un pourrait il, soit me mettre sur la voie, soit me renvoyer dans mes 22 en disant, “t’as pas le niveau gros nOOb, laisse faire les codeurs burnés!!!”

Bon, je suis particulièrement mauvais comme programmeur, mais je propose une solution pas trop compliquée : lire l’entrée de l’utilisateur en string (%s au lieu de %ld). La tu devrais pas avoir de problèmes quoi qui soit rentré. Ensuite tu peux convertir en chiffre avec la fonction strtol par exemple et si c’est pas un chiffre qui a été tapé ça devrait pas planter tout.

En attendant que quelqu’un qui sait vraiment programmer donne une solution mieux…

ou alors tu peux faire un fflush (stdin) juste après ton scanf…
en fait, le truc c’est que tant que t’as pas de chiffre dans ton buffer d’entrée, bah ton programme supprime pas ce qu’il y a dedans, donc il le supprime jamais.
le fflush va te vider tout ca comme un grand

Je pense que la solution de Tiennos est la plus simple ; avec un bout de code comme ca :

[quote]printf(“3.dur\n\n\t”);
scanf("%s",entree);

  difficulte = strtol(entree,NULL,0);
  
  if ( difficulte < 1 || difficulte > 3 ) {
       printf("Saisissez un chiffre entre 1 et 3 !\t");
       continue;
  }[/quote]

ca devrait etre bon

Remarque : un conseil : il peut être plus simple (selon moi, chacun son truc) de faire des boucles while infinie (while (1)) comme ca tu sais exactement quand tu vas sortir (à l’instruction break)

Ceci devrait te depanner:

[code]#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define STR 255

int main()
{
char buf[STR];
char *ep = NULL;
int nb = 0;

printf(« Number ? »);
scanf("%s", buf);
nb = strtol(buf, &ep, 10);
if (buf[0] == 0 || *ep != 0)
printf(« Not a number\n »);
else
printf("%d\n", nb);
return 0;
}[/code]

Attention au buffer overflow si la chaine entree depasse 255 char, dans ce cas la, tu te prendra un segfault dans les dents :stuck_out_tongue:
Pour le reste, tu devrais avoir saisi le truc.

[HS: Pour les constantes, je te suggere d’utiliser les instructions preprocesseurs, c’est plus C]

alors déjà merci à tous pour votre aide
je dois avouer que je n’ai pas tout compris mais ça m’a en tout cas mis sur une piste
je ne plaisanter pas quand je disais que j’avais quatre heures de C derriere moi
je m’y suis mis ce matin, et les chaines de caractéres,string et autre joyeuseté, j’avais pas encore vu ça (c’est que c’est vachement plus loin dans le tuto).

mais je vous remercie de m’avoi mis sur la piste
voilà comment j’ai corrigé mon problème comme un sale
aprés chaque scanf je place ceci:

scanf("%*[^\n]"); scanf("%*1[\n]");
ce qui vire la saisie érronée pour me mettre un beau 1 à la place (ce qui doit se rapprocher du fflush preconisé par molyss plus haut)
par contre je me penche de suite sur la technique de tiennos, joliment mise en pratique par clec, ça va m’etre trés utile pour la suite

enfin seagull, ton bout de code a l’air de poutrer, je m’y attache dés que je sais ce que sont vraiment les defines :stuck_out_tongue:

ah oui, au fait, on me dit dans mon oreillette que faie des boucles while infinie c’est trés mal.
dois je en déduire que c’est une mauvaise habitude à prendre en débutant mais qu’en pratique ça sert tous les jours?

Joli conseil de merde. Les boucles infinis, c’est le mal ABSOLU. Si tu as une condition de sortie, tu la mets dans le while ET PUIS C’EST TOUT.

Bon sinon ton code est chiant a lire parce que pas indente (je sais, c’est reloud ici), Jojosan avait file un lien sympa qui permettait de regarder et d’editer le code, mais je retrouve plus.

LoneWolf
Die die die infinite loop, DIE :stuck_out_tongue:

Bof en C ou en C++ le while(1) c’est un classique qui fait parti des convention. Quand t’as une structure un peu complexe et pour faire du code propre et lisible, c’est souvent mieux un bon break bien place que de devoir aller a la fin du while sans rien faire, revenir au test de la condition et apres sauter…

Sinon le topic fait un peu truc d’un autre siecle quand meme :stuck_out_tongue: ha ouai, c’est du C, excusez… ok ok :stuck_out_tongue:

Juste une petite précision pour rester dans la norme :
En C les commentaires c’est « /* Blabla */ » et pas « // »
N’en mets pas des tartines non plus :wink:

Ici tu peux regarder les différents style d’indentation.

Vala

[quote]En C les commentaires c’est « /* Blabla */ » et pas « // »
N’en mets pas des tartines non plus :wink:

le topic fait un peu truc d’un autre siecle quand meme

Joli conseil de merde. Les boucles infinis, c’est le mal ABSOLU.

ton code est chiant a lire parce que pas indente[/quote]
oui bon je fais mon mea culpa
oui le C c’est vieux et moche
oui mon code n’est pas super top optimisé
mais je reprécise que j’y connait que dalle :stuck_out_tongue:
je me coltine un tutorial que j’essaye de suivre à la lettre
on me dit fait comme ceci, hop bete et discipliné je le fais
et si je commente c’est juste pour m’y retrouver moi meme
mais je prends bonne note de tout ça:

  1. les boucles infinie c’est mal
  2. les commentaires c’est avec /~~/ et pas des tonnes
  3. il faut indenter (sur ce coup là google fut mon ami) mon code.
  4. quatre heure de pratique c’est pas assez pour poster sur la cafzone :stuck_out_tongue:
  5. le C c’est pour les nuls( ça tombe bien j’en suis un!!)

merci à tous

Ben non au contraire :stuck_out_tongue:

1) les boucles infinie c’est mal
Mheu non, pas forcement, faut juste savoir ce qu’on fait.

2) les commentaires c’est avec /~~/ et pas des tonnes
A part a raconter des evidences, les commentaires, y a pas de raison de se limiter. Si c’est pour faire
i++; /* incremente i */ effectivement :stuck_out_tongue: mais sinon… Et puis // … si ca marche, on va pas chipoter, c’est de la prise par derriere d’insecte volant a ce niveau je trouve…

3) il faut indenter (sur ce coup là google fut mon ami) mon code.
Ha ca oui!

4) quatre heure de pratique c’est pas assez pour poster sur la cafzone :stuck_out_tongue:
Mais si :P.

5) le C c’est pour les nuls( ça tombe bien j’en suis un!!)
Non, au contraire, pour moi le C c’est pour ceux qui savent parfaitement ce qu’ils font si on veut en faire comme il faut vu que la moindre erreur est facile a faire et pardonne pas (ce qui est aussi la raison pour laquelle on peut argumenter que c’est mieux pour apprendre, mais c’est douloureux aussi du coup…).

toute façon ya pas de secret, on a jamais fait mieux que le pascal pour apprendre :stuck_out_tongue:
la porte c’est par où ?

Faut pas écouter les vieux ronchons qui te reprochent de pas connaitre par coeur la norme, que tu sais pas faire des listes chainees et patati et patata :stuck_out_tongue:
Tu sais pas faire grand chose, c’est pas grave ça va venir et vu le nombre de gars qui savent programmer en C dans le coin ce serait dommage de pas en profiter.

Ca ça dépend surtout de ce que tu veux faire. Comme pour tous les langages en fait. Mais sinon quand t’auras bien pris la main avec le C, passe au C++ et t’auras l’impression d’avoir trouvé l’illumination ! :stuck_out_tongue:

Sinon, je voudrais aussi m’auto-congratuler pour avoir trouver la solution kivabien. Ca m’avait l’air sale quand je l’ai trouvée, mais en fait non. Wouhouuuuuu !
Oui j’aime me jeter des fleurs ET ALORS ?

Tout mettre dans le main, c’est mal. Je sais que tu débutes et que le programme n’est vraiment pas ce qu’il y a de plus compliqué, mais autant utiliser de bonne méthode dès le départ.