pfffff: bon moi j'y arrive pas avec ce foutu programme !
j'ai beau chercher je vois pas le probleme dans ce foutu code à chaque fois , c'est pareil : il me tape que j'ai trouvé la lettre meme pour celles qui font pas partie du mot . c'est énervant et je perd mon temps !
soit le "MotCopie = strchr(MotSecret,"%c");" est fautif ou alors le '%c' est à remplacer par autre chose !!
char* strchr(const char* MotSecret, int caractereARechercher);
int main()
{
char MotSecret[] = "MARRON" , LettreSecrete = NULL , *MotCopie = NULL ;
int i = 0 , coups = 10 ;
printf("bienvenue dans le jeu du pendu\n");
printf("vous devez deviner le mot cache en 10 coups ou moins\n");
for (i = 0; i<10; i++)
{
printf(" choisissez une lettre\n");
scanf("%c" , &LettreSecrete);
while(getchar()!= '\n'){}
MotCopie = strchr(MotSecret,"%c");
if(LettreSecrete != NULL)
{
MotCopie = malloc(sizeof(char));
if(MotCopie == NULL)
{
exit(0);
}
{
printf("bravo ! vous avez trouve une lettre\n");
printf("%c",*MotCopie);
}
}
else
{
printf("rate , il vous reste %d coups\n", coups);
coups--;
}
}
return 0;
}
j'ai essayé de faire ce truc moi meme avant de regarder la correction donné par le prof . mais je cale sur la raison pour laquelle ce code ne fait pas la difference entre les lettres du mot et celle que j'entre !!!
Bon apparemment les fonctions ne sont pas connues à ce stade. Ca expliquerait.
- Edité par michelbillaud il y a environ 8 heures
Ah oui, bonne remarque ! (Ça expliquerait ainsi pourquoi DavidBerger2 redéclare 'strchr' alors qu'elle l'est déjà si on #inclut <string.h>.)
-----------------
DavidBerger2 : il ne manquerait pas un 'else' entre les lignes 26 et 27 ? (ou bien ce sont les accolades des lignes 27 et 30 qui sont inutiles ?)
Ligne 29 : tu utilises le format %c qui est valable pour un caractère, pas pour une chaîne de caractère ; il faut utiliser %s. Ou alors, si tu veux juste afficher un caractère, il ne faut pas afficher la variable *MotCopie mais MotCopie[0] (ou quelque chose comme ça).
(Ce ne sont pas les erreurs qui expliquent le problème que tu soulèves, mais tant qu'on y est...)
Par ailleurs je ne comprends pas bien l'algorithme. Par exemple à quoi sert le 'if' de la ligne 19 ? À vérifier que le 'scanf' a bien fonctionné ? Sauf que ça mène à afficher "raté". Donc c'est plutôt MotCopie qu'il faut mettre dans le test, non ? (S'il est égal à NULL, c'est que la fonction 'strchr' n'a rien trouvé.) Oui mais tu modifies MotCopie ensuite (avec la ligne 22), qu'est-ce que c'est que ce binz ?
Faudrait poser à plat l'algorithme, à partir de la description du jeu
IDEE DU JEU :
- le joueur essaie de trouver un mot connu de l'ordinateur.
- à chaque étape il tape un caractère
- quand il a trouvé tous les caractères, il a gagné
- quand il trouve un (nouveau ?) caractère, il en est informé
- il a un nombre de coups pour y arriver. Ou il peut avoir un certain nombre d'échecs (pas tout à fait pareil). Pas clair, il y a un choix à faire.
* à partir de là, on peut commencer à développer.
ALGORITHME version 1 :
tant que c'est pas fini
demander un caractère
mettre à jour
- le nombre de caractères restant à trouver
- le nombre de coups restant à jouer
si il n'y a plus de caractères à trouver
c'est gagné, et c'est fini
si il n'y a plus de coups à jouer
c'est perdu, et c'est fini
à développer bien sur.
- Edité par michelbillaud 19 avril 2018 à 12:49:14
Je soupçonne que ce que tu as fait avec MotCopie n'a pas de sens.
− Ligne 4 : il est déclaré comme un pointeur de char, donc a priori pour représenter une chaîne de caractères, et initialisé à NULL.
− Ligne 16 : il pointe vers la première occurrence de LettreSecrete dans MotSecret. Donc MotCopie est désormais une chaîne de caractères commençant à ce caractère et finissant à la fin de la chaîne MotSecret. Du moins si la lettre secrète figurait dans MotSecret. Sinon, MotCopie vaut toujours NULL.
− Ligne 19 : on teste si LettreSecrete est égal à NULL. Non, c'est MotCopie qu'il faut tester, puisque c'est lui qui vaut NULL si on n'a pas trouvé la lettre. Sinon je ne vois pas à quoi sert ce test : LettreSecrete ne vaut NULL que si le scanf n'a pas fonctionné, et encore (?). Mettons que tu t'es trompé, c'était MotCopie que tu voulais tester.
− Ligne 22 : tu redéfinis MotCopie, qui pointe désormais vers un case d'un octet (un, pas deux !), donc ne pouvant plus recevoir qu'un caractère. C'est idiot : la seule chaîne qui rentrera là-dedans, c'est la chaîne vide ! (à cause du '\0' final)
− Ligne 23 : OK, tu testes si le 'malloc' a fonctionné.
− Ligne 29 : affichage de *MotCopie qui, à ce stade, ne vaut rien puisque tu as alloué un octet de mémoire mais tu ne l'as pas initialisé : il ne pointe vers aucun emplacement valide.
Je ne veux pas te démoraliser, mais c'est un peu n'importe quoi... Est-ce que tu as une idée précise de ce que représente MotCopie ? Il représente une lettre ou un mot ?
Ah OK ! Mais aux lignes 16 et 22, MotCopie ne joue pas le même rôle...
Ligne 16, on vérifie que la lettre proposée fait partie du mot. Effectivement, la fonction 'strchr' est utile. Mais il ne faut pas mettre le retour de cette fonction dans MotCopie. Ce qu'il faudrait, c'est juste vérifier que cette fonction ne retourne pas NULL, donc que la lettre proposée fait bien partie du mot. Du coup je ferais plutôt quelque chose comme :
scanf("%c" , &LettreSecrete);
while(getchar()!= '\n'){}
if (strchr(MotSecret, LettreSecrete) != NULL) // attention au 2ème argument !
{
/* la lettre saisie figure dans MotSecret */
Ligne 22, on incrémente MotCopie en lui ajoutant la lettre proposée, vu qu'elle figure dans le mot. Dans ce cas il faut allouer un nouvel octet qui s'ajoute à ceux déjà alloués. Or la ligne 22 se contente d'allouer un octet, du coup on perd ce qui a été alloué les fois précédentes.
Comme je ne suis pas super à l'aise avec les pointeurs, j'aurais défini MotCopie comme une chaîne de caractères de 25 lettres (car aucun mot de la langue française ne dépasse cette valeur), donc quelque chose comme :
char MotCopie[26] ;
Pour compléter au fur et à mesure les lettres, il faut un compteur qui compte le nombre de lettres trouvées. Au début :
int compteurLettres = 0 ;
Et à la ligne 22 on aurait :
MotCopie[compteurLettres++] = LettreSecrete ;
Explication : on ajoute la lettre trouvée dans la chaîne, puis on incrémente le compteur des lettres afin que la prochaine lettre soit écrite à la case suivante.
À la ligne 29, on veut afficher la lettre trouvée, eh bien il suffit d'afficher LettreSecrete (avec %c) : c'est elle qu'il faut afficher et non pas MotCopie, qui a une autre signification (c'est la liste des lettres déjà trouvées).
Bien sûr, à la sortie de la boucle, il faudra ajouter le caractère nul pour fermer la chaîne MotCopie au cas où on voudrait l'afficher en entier :
MotCopie[compteurLettres] = '\0' ;
(pas besoin d'incrémenter le compteur à cet endroit).
Remarque : il pourrait être intéressant de vérifier que LettreSecrete n'a pas déjà été trouvée, donc appeler 'strchr' dans MotSecret (pour vérifier que la lettre y figure), mais aussi dans MotCopie (pour vérifier qu'on ne l'a pas déjà trouvée − je sais, c'est idiot : le joueur ne va pas re-proposer une lettre déjà trouvée, mais bon...) Dans ce cas, il faudra que MotCopie finisse par le caractère '\0' dès l'initialisation, donc il faudra l'initialiser avec une chaîne de 26 caractères nuls. À moins qu'il y ait une autre façon de faire ?
Il y a plein d'autres langages qui n'ont pas de pointeurs ! Mais ils ne sont pas plus simples pour autant. Pour moi, le langage simple à apprendre qui me vient immédiatement à l'esprit est le Fortran 77 (pas le 90 qui possède des pointeurs).
Si on veut se tourner vers du Java, autant faire du Scala ou encore du Kotlin. Sinon,niveau langages assez cools pour débuter, tu as Python ou Ruby. Mais dans tous les cas, le plus important est d’avoir un bon tutoriel.
essaie Processing, c'est amusant, ça permet de faire des choses très sympa, et ça fait une initiation à Java sans tout le tintouin public static void main qui rebute les débutants.
J'ai essayé, je n'aime pas, ça m'a l'air trop compliqué pour moi (bien plus que le C, peut-être même encore plus que le C++ ce qui n'est pas peu dire).
.
michelbillaud :
> ça fait une initiation à Java sans tout le tintouin public static void main qui rebute les débutants.
.
Voilà, c'est en effet ce tintouin qui m'a rebuté. Et aussi (c'est lié) l'obligation de programmer avec des objets (par exemple chaque fichier source doit correspondre à un objet, je crois).
J'ai réfléchi à une réponse, j'ai commencé à taper quelque chose, puis j'ai renoncé. Les pointeurs sont la spécificité du C (c'est ce qui lui permet d'être aussi un langage de bas niveau) ; sans les pointeurs le C n'a plus de raison d'être (autant programmer en Fortran ou en Pascal − qui possède lui aussi des pointeurs, d'ailleurs). C'est donc un sujet très vaste, je ne sais pas si on peut synthétiser une réponse dans un simple message.
Un exemple parmi tant d'autres : les pointeurs permettent de fabriquer des listes chaînées, des piles ou des arbres de recherche. Je ne sais pas s'il serait possible de fabriquer des arbres de recherche sans pointeurs (avec des tableaux ?). Et sans arbres de recherche, pas de moteur de recherche par exemple. Mais bon, il y a une foultitude d'exemples...
C'est pas qu'on a besoin de pointeurs en C. C'est que C est un langage qui est fait pour les utiliser.
C a été conçu comme un langage de bas niveau qui permet de manipuler des données dont les types de base sont des entiers, des octets, des flottants et des adresses.
- Edité par michelbillaud 21 avril 2018 à 19:10:06
enfin bon , je pense que vous avez compris ce que je veux dire ; par exemple je voudrais dire : lettre secrete se trouve dans mot secret ou fait partie de mot secret ; on dit ça comment?
MotSecret(LettreSecrete) ? ou l'inverse : LettreSecrete(MotSecret) ? ou une autre façon de faire peut etre ?
enfin bon , je pense que vous avez compris ce que je veux dire ;
Faut pas penser ça. Je croyais que la question portait sur la dénomination des concepts en C, alors qu'il s'agit - si je comprend mieux -du choix d'un nom de fonction. Ce qui n'a absolument rien de spécifique au langage C.
Ca n'a rien à voir non plus avec des _variables_. Une fonction qui dit si une lettre apparait dans un mot, ça prend comme paramètres des _valeurs_: une lettre et un mot . Qui peuvent être contenues dans des variables ou pas. Je peux me demander si la _constante_ 'z' est dans un mot, par exemple. Ou le caractère 'a'+i, avec i entre 0 et 25. Dans ce cas c'est une expression.
Revenons à nos moutons. Choisir un nom parlant pour une fonction.
on a une lettre
on a un mot
la fonction détermine si la lettre est dans le mot, ou pas. Elle répond vrai ou faux.
Donc déjà, c'est une fonction à deux paramètres.
La question à se poser, c'est de voir ce que ça donne quand on emploie la fonction. Si on écrivait du pseudo-code pour expliquer ce qui se passe, ça ressemblerait à
L = 'x'
M = "ornithorynque"
...
si la lettre L est dans le mot M alors // ceci
afficher "bravo"
alors pourquoi pas
if ( lettre_dans_mot(L, M) ) {
printf("bravo\n");
}
En fait sizeof(char), c'est la taille d'un octet, en nombre d'octets, donc ça vaut exactement 1. Ton malloc réserve de l'espace pour un caractère, et retourne une adresse qui ne va pas rentrer dans LettreTrouvee, qui est un char. Le compilateur doit pousser quelques hurlements à ce sujet, tu devrais en ternir compte.
Tu ne devrais pas t'embarquer dans de l'allocation dynamique tant que tu n'as pas compris le reste. D'autant que ça ne sert strictement à rien pour ce problème.
bonjour michelbillaud pourquoi mettre Bool dans ton exemple alors que le site ne m'a pas appris ça ?
bool, pas Bool.
Parce qu'il est très important, pour la programmation, de connaître la notion d'indicateur " logique", qui est maintenant (depuis un nombre certain d'années) disponible en C sous forme du type bool apporté par "stdbool.h".
La vraie question, c'est pourquoi le site n'en parle pas. Hein, oui, pourquoi ?
Quand je dis un certain nombre d'années, c'est le standard C99. C'est pas exactement une nouveauté, mille neuf cent quatre vingt dix neuf.
Autrefois, en C, on simulait les "booléens" par 0 (pour dire "faux") et n'importe quoi d'autre qui signifie "vrai". Mais c'était avant, il y a très longtemps, dans une autre galaxie, quasiment.
Depuis, ça a changé. On a le type bool, et les constantes true et false.
Et donc comme le cours - qui est très loin d'être à jour - n'en parle pas, et que OC ne voit pas son intérêt économique dans la rédaction d'un cours plus décent, il faut bien que quelqu'un en parle.
j'ai du mal dans le malloc .