Je suis actuellement de continuer le TP Pendu en utilisant un dico cette fois mais j'ai l'erreur que j'ai indiqué dans le titre qui se produit... J'ai situé à l'aide de printf le moment ou le programme s'arrête et il se situe juste après le printf ("Bienvenu [...]"), pas avant ni après... Je ne sais pas du tout pourquoi elle se produit... Voici mon code :
main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <time.h>
#include "pendu.h"
#define TAILLE_LECTURE 20
int main (int argc, char *argv[]) {
int i = 0, nbrCoups = 0, nbrLigne = 0, randomWord = 0 ;
char lettreEntree = 0 ;
char lineFile[TAILLE_LECTURE] = "" ;
printf ("\n\nBienvenu dans Le Pendu !\n\n") ;
FILE* dico = NULL ;
dico = fopen ("pendu.dico", "r") ;
char *fileWords = NULL ;
if (dico != NULL) {
while (fgets(NULL, TAILLE_LECTURE, dico) != NULL) {
nbrLigne++ ;
}
printf ("\n\n%d\n\n", nbrLigne) ;
if (nbrLigne == 0) {
error ("Il n'y a pas de mots dans le dictionnaire") ;
}
const int MAX = nbrLigne, MIN = 1 ;
srand(time(NULL)) ;
randomWord = (rand() % (MAX - MIN + 1)) + MIN ;
for (i = 0 ; i <= nbrLigne ; i++) {
if (nbrLigne == randomWord) {
fileWords = malloc (strlen(fgets(NULL, TAILLE_LECTURE, dico)) * sizeof (char)) ;
fgets(fileWords, TAILLE_LECTURE, dico) ;
}
if (fileWords == NULL) {
exit (0) ;
}
printf ("\n\n%s\n\n", fileWords) ;
}
} else {
error ("Impossible d'ouvrir le fichier pendu.dico") ;
}
//do {
printf("\nIl vous reste %d coups a jouer\n", nbrCoups) ;
//printf ("Quel est le mot secret ? %s\n", wordsHide) ;
printf("Proposez une lettre : ") ;
lettreEntree = lireCaractere() ;
//} while () ;
free (fileWords) ;
return 0 ;
}
pendu.h
#include <stdio.h>
#include <stdlib.h>
//Fonctions
char lireCaractere() {
char caractere = 0 ;
caractere = getchar() ; // On lit le premier caractère
caractere = toupper(caractere) ; // On met la lettre en majuscule si elle ne l'est pas déjà
// On lit les autres caractères mémorisés un à un jusqu'au \n (pour les effacer)
while (getchar() != '\n') ;
return caractere; // On retourne le premier caractère qu'on a lu
}
void error (char chaine[1000]) {
printf ("\n\n%s !\n\n", chaine) ;
exit (0) ;
}
Cordialement et Merci d'avance !
PS 1 : JE sais que mon code ne ressembles pas du tout à celui de la solution (que j'ai regardé en essayant de résoudre le problème mais il n'utilise pas du tout la même méthode)
PS 2 : Les commentaires bizarres sont des morceaux de code du pendu sans dico qui ne me servent pas pour l'instant
- Edité par Jupiter41 20 septembre 2017 à 16:08:04
Ok mais pourquoi sa marche alors ? et ce n'est pas vraiment le problème
EDIT : Bon je viens de me rendre compte après une pause que le code de ma boucle for c'est du grand n'importe quoi. J4ai donc supprimé tout ce qui était allocation dynamique pour l'instant.
Après que le programme est choisi un nombre aléatoire j'essaye de copier le mot à la ligne choisi précédemment, mais je n'y arrive pas (secretWord n'est pas égale au mot) voici le code de ma boucle for :
const int MAX = nbrLigne, MIN = 0 ;
srand(time(NULL)) ;
randomWord = (rand() % (MAX - MIN + 1)) + MIN ;
for (i = 0 ; i < nbrLigne ; i++) {
secretWord[i] = "" ;
fgets(secretWord, TAILLE_LECTURE, dico) ;
if (nbrLigne == randomWord) {
break ;
}
}
} else {
error ("Impossible d'ouvrir le fichier pendu.dico") ;
}
- Edité par Jupiter41 20 septembre 2017 à 18:46:34
2) Ligne 29 Le premier paramètre de fgets ne peut pas être NULL (idem ligne 53)
3) Toujours ligne 53 tu y fais des malloc en boucle sans free (tu free seulement le dernier malloc à la fin de ton programme).
4) toujours dans la même boucle ligne 55 tu tentes de relire les lignes du fichier alors que tu est positionné à la fin du fichier car tu as déjà lu le fichier précédemment pour compter tes ligne.
PS : pour ta correction apporté dans ton 2éme post tu n'as pas mis le code entier, notamment la déclaration de secretWord.
Salut ! Sa ne marche toujours pas et si j'ai bien compté fileWords = "\n\n\n" (3 saut de lignes) Voici le code complet de main.C (pendu.h n'a pas changé :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <time.h>
#include "pendu.h"
#define TAILLE_LECTURE 20
int main (int argc, char *argv[]) {
int i = 0, nbrCoups = 10, nbrLigne = 0, randomWord = 0 ;
char lettreEntree = 0 ;
char lineFile[TAILLE_LECTURE] = "" ;
printf ("\n\nBienvenu dans Le Pendu !\n\n") ;
FILE* dico = NULL ;
dico = fopen ("pendu.dico", "r") ;
char secretWord[50] = "", hiddenWord[50] = "" ;
if (dico != NULL) {
while (fgets(lineFile, TAILLE_LECTURE, dico) != NULL) {
nbrLigne++ ;
}
if (nbrLigne == 0) {
error ("Il n'y a pas de mots dans le dictionnaire") ;
}
const int MAX = nbrLigne, MIN = 0 ;
srand(time(NULL)) ;
randomWord = (rand() % (MAX - MIN + 1)) + MIN ;
for (i = 0 ; i < nbrLigne ; i++) {
secretWord[0] = '\0' ;
fgets(secretWord, TAILLE_LECTURE, dico) ;
if (nbrLigne == randomWord) {
break ;
}
}
} else {
error ("Impossible d'ouvrir le fichier pendu.dico") ;
}
printf ("\n\n%s\n\n", secretWord) ;
//do {
printf("\nIl vous reste %d coups a jouer\n", nbrCoups) ;
//printf ("Quel est le mot secret ? %s\n", wordsHide) ;
printf("Proposez une lettre : ") ;
lettreEntree = lireCaractere() ;
//} while () ;
return 0 ;
}
- Edité par Jupiter41 21 septembre 2017 à 18:42:21
4) toujours dans la même boucle ligne 55 tu tentes de relire les lignes du fichier alors que tu est positionné à la fin du fichier car tu as déjà lu le fichier précédemment pour compter tes ligne.
Non, ça ne fonctionne pas comme ça: tu écrases le \0 - indicateur de fin de chaîne - avec une '*'. Et donc toutes les fonctions qui traitent / utilisent les chaines de caractères (dont printf() et strlen() font partie) vont planter, sauf chance - ou malchance, au choix - car elles ne trouveront plus le \0. Attends d'avoir lu la partie du tutoriel sur l'allocation dynamique pour envisager ce genre de chose.
- Edité par edgarjacobs 24 septembre 2017 à 18:02:08
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
Ta méthode marche ! J'ai donc copier le code de mon pendu sans dico et fait les modifs nécessaires, mais je me retrouve avec 2 bugs :
- Un "\n" se rajoute à la fin du dernier mot (vu avec le printf de victoire)
- Le programme ne fait rien si l'utilisateur entre une mauvaise lettre... sauf si je vérifie la valeur de goodLettre et la bizarrement sa marche correctement...
Mon code :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <time.h>
#include <ctype.h>
#include "pendu.h"
#define TAILLE_LECTURE 50
int main (int argc, char *argv[]) {
int i = 0, nbrCoups = 10, nbrLigne = 0, randomWord = 0, curline = 0, tailleCaractere = 0 ;
char lineFile[TAILLE_LECTURE] = "", secretWord[50] = "", hiddenWord[50] = "", lettreEntree = 0, lettreTableau = 0 ;
printf ("\n\nBienvenu dans Le Pendu !\n\n") ;
FILE* dico = NULL ;
dico = fopen ("pendu.dico", "r") ;
bool goodLettre = false ;
if (dico != NULL) {
while (fgets(lineFile, TAILLE_LECTURE, dico) != NULL) {
nbrLigne++ ;
}
if (nbrLigne == 0) {
error ("Il n'y a pas de mots dans le dictionnaire") ;
}
srand(time(NULL)) ;
randomWord = rand() % nbrLigne ;
rewind (dico) ;
do {
fgets(secretWord, TAILLE_LECTURE, dico) ;
curline++ ;
} while (curline < randomWord) ;
} else {
error ("Impossible d'ouvrir le fichier pendu.dico") ;
}
curline = 0 ;
while (curline < (strlen(secretWord)-1)) {
strcat(hiddenWord,"*") ;
curline++ ;
}
do {
printf("\nIl vous reste %d coups a jouer\n", nbrCoups) ;
printf ("Quel est le mot secret ? %s\n", hiddenWord) ;
printf("Proposez une lettre : ") ;
lettreEntree = lireCaractere() ;
for (i = 0 ; i < TAILLE_LECTURE ; i++) {
lettreTableau = secretWord[i] ;
if (lettreEntree == lettreTableau) {
goodLettre = true ;
if (hiddenWord[i] == lettreTableau) {
printf("\nVous avez déjà rentré cette lettre ! : %c\n", lettreEntree) ;
nbrCoups -- ;
} else hiddenWord[i] = lettreTableau ;
}
}
if (goodLettre == false) {
printf("\n%c est une mauvaise lettre !\n", lettreEntree) ;
nbrCoups -- ;
}
} while (won(hiddenWord) != 1 && nbrCoups > 0) ;
if (nbrCoups > 0) {
printf ("\nFelicitations le mot mystere est bien : %s !\n", secretWord) ;
} else {
printf ("\nVous n'avez plus de coups vous avez donc perdu ! \n\n") ;
}
fclose (dico) ;
return 0 ;
}
//Fonctions
char lireCaractere() {
char caractere = 0 ;
caractere = getchar() ; // On lit le premier caractère
caractere = toupper(caractere) ; // On met la lettre en majuscule si elle ne l'est pas déjà
// On lit les autres caractères mémorisés un à un jusqu'au \n (pour les effacer)
while (getchar() != '\n') ;
return caractere; // On retourne le premier caractère qu'on a lu
}
void error (char chaine[1000]) {
printf ("\n\n%s !\n\n", chaine) ;
exit (0) ;
}
int won(char word[TAILLE_LECTURE]) {
int i, fullWord, gagner = 0 ;
fullWord = 0 ;
for (i = 0 ; i < TAILLE_LECTURE ; i++) {
if (word[i] != '*') {
fullWord++ ;
}
}
if (fullWord == TAILLE_LECTURE) gagner = 1 ;
return (gagner) ;
}
- Un "\n" se rajoute à la fin du dernier mot (vu avec le printf de victoire)
Le \n "ne se rajoute pas", il est lu par le fgets():
man fgets() said:
A newline character makes fgets stop reading, but it is considered a valid character by the function and included in the string copied to str.
Pour solutionner cela, il faut juste faire un petit test:
char *s;
s=strchr(string,'\n');
if(s!=NULL)
*s=0;
ce qui supprime le \n dans string si il existe.
Jupiter41 a écrit:
- Le programme ne fait rien si l'utilisateur entre une mauvaise lettre... sauf si je vérifie la valeur de goodLettre et la bizarrement sa marche correctement...
Lignes 80 et 156: ce n'est TAILLE_LECTURE qu'il faut employer, mais un strlen().... je te laisse chercher. Cela e solutionnera peut-être pas le problème (mais la modification est nécessaire), mais je n'ai pas envie de tester ton code.
- Edité par edgarjacobs 26 septembre 2017 à 20:57:32
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
Je n'ai pas testé ton code, mais oui il doit fonctionner. Juste un défaut: si le mot à rechercher est "anticonstitutionnellement", que j'ai déjà entré la lettre 'n', que nbrCoups vaut 5, et que je entre à nouveau la lettre 'n', que va valoir nbrCoups à la fin de la boucle qui commence ligne 86 ?
- Edité par edgarjacobs 27 septembre 2017 à 20:03:57
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
alors ceci va fonctionner:
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent