Le souci, c’est que tu n’essaies pas vraiment de faire un code correct ; là si ton programme se met à fonctionner, on pourra juste dire qu’il est « tombé en marche », par chance. Quand tu écris une ligne de code, tu dois savoir pourquoi tu l’écris, pas l’écrire parce que tu penses que ça va corriger ton code. Donc, on va reprendre les choses calmement. Comment fonctionne le jeu du pendu ?
- On choisit un mot à faire deviner.
- On affiche des étoiles.
- On demande une lettre.
- On regarde si elle est dans le mot et où elle est.
- On retourne à l’étape 2.
Et on s’arrête si on a trouvé le mot où s’il ne reste plus d’essais.
Comment faire les différentes étapes dans ton code ? On note déjà que les étapes 2 à 5 seront dans une boucle
- C’est une étape facile, le mot est fixé.
- Dans ton code, on a
motAffiche
qui est le mot qu’on devra afficher. Au début, il n’a que des étoiles, mais on le met à jour quand on trouve une lettre. Par exemple, si l’utilisateur devine le « A », on remplacera la seconde étoile de motAffiche
par un A
, et donc quand on l’affichera on aura « *A**** » ; si ensuite il trouve le « R », on remplacera les deuxième et troisième étoile de motAffiche
et donc lorsqu’on l’affichera on aura « *ARR** ».
- L’utilisateur tape une lettre, c’est OK dans ton code. Tu peux faire une fonction
getLetter
qui demande la lettre, la met en majuscule et la renvoie (et elle pourrait même demander à l’utilisateur tant qu’il n’a pas rentré de lettre, au cas où il rentre autre chose).
- Ça c’est le travail de la fonction
find
. Regarder si la lettre est dans le mot et où elle est, c’est mettre à jour motAffiche
, comme ça la prochaine fois qu’il sera affiché, les lettres trouvées seront là au lieu des étoiles.
S’arrêter s’il ne reste plus d’essais, tu le fais déjà (reste à rajouter la condition « on a trouvé le mot », ça veut juste dire que motAffiche
et motMystere
sont pareils).
Maintenant, quels sont les problèmes dans ton code.
- Déjà, si on regarde les étapes qu’il doit y avoir dans notre boucle, tu ne les fais pas dans le bon sens. Tu appelles
find
au début de la boucle, avant même d’avoir demandé une lettre à l’utilisateur.
- Dans la fonction
find
, tu affiches des trucs, pourquoi ? Elle doit juste mettre à jour motAffiche
avec la lettre proposée par l’utilisateur, ce qu’elle fait avec le if
dans la boucle for
.
Ça c’est les deux problèmes qui peuvent bien se voir grâce à la structure du programme. Mais même en corrigeant ça, motAffiche
s’affichera peut-être mal (des caractères supplémentaires à la fin). C’est peut-être un problème que tu as observé d’ailleurs. Ça arrive parce que tu n’as pas mis le \0
final à la fin de motAffiche
. Pourtant, ça t’a été dit plusieurs fois sur Discord, donc j’imagine que ça signifie que tu ne sais pas/n’a pas bien compris pourquoi il était important. On va donc rapidement expliquer ça.
En C, une chaîne de caractères, c’est un tableau de caractères… terminé par le caractère \0
. Le truc, c’est qu’il faut savoir où la chaîne se termine. Pour ça, on pourrait avoir une structure avec le tableau et sa taille. Le C a choisi que la chaîne se terminait quand il y avait un \0
. Et donc, pour afficher une chaîne de caractères, on fait quoi ? On fait une boucle while
, et tant qu’on a pas de \0
, on affiche le caractère et on passe au caractère suivant.
void print_string(const char s[]) {
for(size_t i = 0; s[i] != `\0`; i++)
putchar(s[i])
}
Ça signifie que si tu oublies ce \0
à la fin de ton tableau de caractères, lorsque tu voudras afficher la chaîne de caractères correspondante, cette chaîne s’affichera, mais aussi tout ce qu’il y a après jusqu’à ce qu’on tombe sur un \0
. Comme on n’a aucune garantie de ce que peut contenir la mémoire (en vrai, il y a peut-être un \0
à la case juste après la dernière case de notre tableau si on a de la (mal)chance), il ne faut pas l’oublier.