Aller au menu - Aller au contenu

[Plan du site] Vous êtes ici --- > Le Site du Zéro > Les forums > Programmation > Langage C > Problème pour le pendu TP2 de M@teo > Lecture du sujet

Problème pour le pendu TP2 de M@teo

Vous devez être inscrit pour pouvoir poster des messages

RésoluLe problème de ce sujet a été résolu

Page : 1 
Auteur Message
1 visiteur sur ce sujet (1 anonyme)
Page : 1 
Hors ligne bjarni3000 # Posté le 18/07/2008 à 23:45:57
Groupe : Membres
Bonsoir,
j'ai suivi le cours de M@teo sur le langage C mais je coince au pendu(première partie, sans l'utilisation du dictionnaire). J'ai regardé la solution mais il utilise les booléens alors que moi j'ai utilisé un autre tableau différemment. J'ai deux problèmes différents avec ce code:
- il faut que je tape deux fois la première lettre juste du pendu pour qu'elle soit considérée comme correcte.
- le logiciel ne comprend pas que la solution a été trouvée à la fin...

Voilà donc si quelqu'un pouvait m'expliquer ce qui cloche dans ce programme ce serait super parce que moi là je vois pas...ça doit être une faute évidente mais je la vois pas :euh:

voilà le code du main:
Secret (cliquez pour afficher)
Code : C
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "headers.h"

int main(int argc, char *argv[])
{
//Initialisations
  int i=0, nombreCoupsRestants=0, finir=0, echec=0;
  long longueurChaine=0;
  char motSecret[] = "MARRON";
  char* motDecouvert=NULL;
  
  //Initialiser et remplire motDecouvert
  longueurChaine=strlen(motSecret);
  motDecouvert=malloc(sizeof(char) * longueurChaine) ;
  
  
 <couleur nom="bleu"> //LE JEU</couleur>
  printf("--------------------------Bienvenu sur le jeu du pendu--------------------------\n\n");
  nombreCoupsRestants=niveau();
  printf("Vous avez %i coups pour trouver le mot secret.\n",nombreCoupsRestants);
  for(i=nombreCoupsRestants;i>0;i--)
  {
                                    printf("Quel est le mot secret?");
                                    asterix(motSecret, motDecouvert, longueurChaine);
                                    echec=nouvelleSaisie(motSecret, motDecouvert, longueurChaine);
                                    if(echec==0)
                                    {
                                        printf("Il vous reste %i coups pour trouver le mot secret.\n",--nombreCoupsRestants);
                                    }
                                    finir=gagnerPerdre(motDecouvert, motSecret, nombreCoupsRestants);
                                    if(finir==1)
                                    {break;}
                                    else
                                    {continue;}                  
  }
  
  
  
  
  system("PAUSE");	
  return 0;
}


Voilà le fichier de fonctions:
Secret (cliquez pour afficher)
Code : C
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
//Niveau de jeu
int niveau()
  {
      int difficulte=0, nombreCoupsRestants=0;
      printf("Quel difficulte voulez-vous? (1 pour facile, 2 pour moyen ou 3 pour difficile):");
      scanf("%i", &difficulte);
      if(difficulte==1)
      {return nombreCoupsRestants=20;}
      else if(difficulte==2)
      {return nombreCoupsRestants=15;}
      else if (difficulte==3)
      {return nombreCoupsRestants=10;}
      else
      {printf("Erreur d'entree...relancez l'application");}
  } 
//Affiche les astérix ou les lettres trouvées.
void asterix(char* motSecret, char* motDecouvert, long longueurChaine)
{
     int i=0;
     for(i=0;i<longueurChaine;i++)
     {
                                  if (motDecouvert[i]==motSecret[i])
                                  {
                                                                    printf("%c", motSecret[i]);
                                  }
                                  else
                                  {
                                                                    printf("*");
                                  }
     }
}

//Alternative à scanf

char lirecaractere()
{
     char caractere=0;
     caractere=getchar();
     caractere=toupper(caractere);
     while(getchar() != '\n');
     return caractere;
}

//Nouvel essai
int nouvelleSaisie(char* motSecret, char* motDecouvert, long longueurChaine)
{
     int i=0, perdu=0;
     char maLettre='a';
     printf("\nProposez une nouvelle lettre:");
     maLettre=lirecaractere();
     for(i=0;i<longueurChaine;i++)
     {
                                  if (motSecret[i]==maLettre)
                                  {
                                                             motDecouvert[i]=maLettre;
                                  }
                                  else
                                  perdu++;
     }      
     if(perdu==longueurChaine)
     return 0;
     else 
     return 1;      
}


//Gagné ou perdu?!?

int gagnerPerdre(char* motDecouvert, char* motSecret, int nombreCoupsRestants)
{
    
    if(strcmp(motDecouvert,motSecret)==0 || nombreCoupsRestants==0)
    {
                                         if(strcmp(motDecouvert,motSecret)==0)
                                         {                                    printf("Vous avez decouvert le mot secret!");        
                                                                              return 1;
                                         }
                                         if(nombreCoupsRestants==0)
                                         {
                                                                   printf("Vous avez perdu!!!\n");
                                                                   return 1;
                                         }        
    }
    else 
    return 0;
}


Et voilà le fichier de headers:
Secret (cliquez pour afficher)
Code : C
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#ifndef DEF_HEADERS.H
#define DEF_HEADERS.H
int niveau();
void asterix(char* motSecret, char* motDecouvert, long longueurChaine);
int gagnerPerdre(char* motDecouvert, char* motSecret, int nombreCoupsRestants);
char lirecaractere();
int nouvelleSaisie(char* motSecret, char* motDecouvert, long longueurChaine);






#endif


Voilà j'espère que la présentation va sinon dites le moi je corrigerai.
Édité le 18/07/2008 à 23:46:49 par bjarni3000
Hors ligne etrange02 # Posté le 18/07/2008 à 23:57:00
Pourquoi, il en faut une?
Avatar
Groupe : Membres
Il y a un truc que je ne comprends pas : pourquoi fais-tu des pointeurs si tu ne modifie les chaînes pointées dans ta fonction asterix() ?

P.S.: Si tu ne sens pas que les fonctions sont pratiques pour toi, ne les utilisent pas. Attend d'avoir un programme qui fonctionne pour ensuite le découper en fonction.

Aussi, va doucement. Tu n'arriveras à rien si tu code tout d'un seul coup. Ton programme ne fonctionne pas et tu as déjà fait une fonction niveau. Garde-la pour la suite en amélioration. Et il manque un return donc prends ton temps (il se place en fin de fonction).

Rome ne s'est pas faite en un jour.

J'en ai marre des édits !
Édité le 19/07/2008 à 00:03:53 par etrange02

:colere2: Pas de fautes d'orthographe s'il vous plaît et un peu de respect pour la syntaxe :colere2:
 
Hors ligne bjarni3000 # Posté le 19/07/2008 à 22:22:45
Groupe : Membres
En effet j'avais oublié un return...ou plutôt un exit pour le printf du message d'erreur. Ben en faite je suis resté un moment à chercher pourquoi y avait ces problèmes et j'ai rajouté des trucs en même temps comme le niveau de difficulté, ça au moins j'étais sûr que ça fonctionnait ^^. Pour la manière donc j'ai fractionné mon code en fonction, au début j'avais tout fait d'un bloc puis j'ai fragmenté pour que ce soit plus clair et pouvoir mieux trouver les erreurs que j'obtiens...
Pour la fonction asterix...je comprend pas le problème avec le pointeur...on modifie quand même un des tableaux si la lettre correspond donc on doit passer par là non?
Bref suis un débutant donc ça doit être des erreurs grossières mais je les vois pas. Est-ce que quelqu'un verrait ce qui crée mes deux problèmes?
Hors ligne etrange02 # Posté le 19/07/2008 à 22:57:45
Pourquoi, il en faut une?
Avatar
Groupe : Membres
Lorsque tu écrit pointeur[1] = quelque_chose, c'est la case sur laquelle le pointeur pointe. En revanche, *ponteur[1] te donnes la valeur de la variable.

Pour faire simple :
- variable -> valeur de la variable
- &varaible -> adresse de la variable
- pointeur -> valeur du pointeur <=> adresse de la variable
- *pointeur -> valeur de la variable se trouvant à cette adresse <=> valeur de la variable

Donc :
*pointeur = variable
pointeur = &variable

En espérant que cela t'aide un peu !

Personnellement, je créerai une chaine contenant les caractères découverts et les étoiles comme M*RRO* (pour marron). Ensuite, à l'aide d'une boucle du vérifie si tous les caractères sont découverts. Pour le reste, je cherche :p

Il faut que tu saches aussi que lorsqu'une fonction se termine, les variables qui sont incluses dedans sont supprimées à moins de leurs donner un type particulier (je crois que c'est static mais vérifie toujours dans le tuto :-° ).

Dans la fonction main() je te conseil d'utiliser un while à la place du for. Car si je trouve le mot secret en trois coups, je continuerai toujours le jeu alors qu'il est sensé être terminé.
Édité le 19/07/2008 à 23:20:23 par etrange02

:colere2: Pas de fautes d'orthographe s'il vous plaît et un peu de respect pour la syntaxe :colere2:
 
Hors ligne bjarni3000 # Posté le 20/07/2008 à 01:19:08
Groupe : Membres
Hello,

je mélange encore souvent les choses sur les pointeurs c'est vrai mais tableau[0] n'est-il pas égal à *tableau. Enfin me semblait avoir vu ça à qq part dans le cours après je peux confondre. Pourtant ça marche quand même la fonction asterix...enfin j'ai trouvé ce qui clochait, ça avait déjà été posé en question sur le forum en faite. C'est dû à mon scanf dans la fonction niveau, j'ai pas vidé le buffer...

J'ai fait la modif que t'as dites mais bof pas de résultat différent. Je pourrais faire une boucle en effet pour comparer les résultats mais arriverais-tu à m'expliquer pourquoi la fonction gagnerPerdre ne fonctionne pas? Elle ne voit jamais motSecret et motDecouvert identique alors qu'en les testant juste avant ils le sont...(j'ai testé dans le main la fonction motDecouvert et ça joue o_O ). Est-ce une mauvaise utilisation de la fonction strcmp??
Hors ligne etrange02 # Posté le 20/07/2008 à 02:41:05
Pourquoi, il en faut une?
Avatar
Groupe : Membres
Je ne pense pas que ta fonction gagnerPerdre() ne fonctionne pas. Je dirai plus que le problème se trouve dans ta fonction main(), le résultat que tu obtiens est mal interprété. Si tu as changer des choses, peux-tu me les remettre, pour savoir où tu en es et évite les balises "secret".

Merci.

Je ne sais pas si cela joue mais essaye de ne faire qu'un seul return dans ta fonction gagnerPerdre(). Tu retournerais dans ce cas la valeur d'une variable.

En attendant, il ne t'es pas interdit d'afficher en plein milieu de ton programme des chaînes ou des variables pour savoir quoi et comment évolue telle ou telle chose ;) .
Édité le 20/07/2008 à 02:58:15 par etrange02

:colere2: Pas de fautes d'orthographe s'il vous plaît et un peu de respect pour la syntaxe :colere2:
 
Hors ligne bjarni3000 # Posté le 21/07/2008 à 23:56:59
Groupe : Membres
Bonsoir!

Vu le temps destiné à répondre, les choses ont avancé et j'ai une bonne et une mauvaise nouvelle :p
J'ai testé avec plein de printf partout pour voir jusqu'où ça fonctionnait et j'ai fini par trouver mes deux solutions:
Le premier problème, celui de la double réponse juste à mettre, était dû à mon scanf dans la fonction niveau(). Cette super fonction gardait le "enter" apparemment plus que je ne le pensais. Je me méfierai d'avantage à l'avenir.
Le second, celui du jeu qui ne se finissait pas, était dû et bien à une faute d'initialisation si on peut dire. En fait j'ai fait le malloc mais pas spécifié que le dernier caractère serait '\0' donc ça continuait...

Bon ça c'est pour les problèmes précédents mais j'en ai rencontré un autre avec la partie dictionnaire et là j'ai eu beau refaire des printf je trouve pas...A voir il y a un problème avec le strlen dans void motpioche(...) mais je comprend pas pourquoi donc si quelqu'un arrive à me trouver une explication ce serait super. Le pire c'est que depuis que j'ai écris cette ligne même si je l'enlève le programme plante...et M@teo21 a fait qqch du même genre d'après le corrigé. Bref un casse-tête je comprend pas...HELP o_O
Voilà le code:
Le main:

Code : C
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "headers.h"

int main(int argc, char *argv[])
{
  //Initialisations  
  int i=0,j=0, nombreCoupsRestants=0, finir=0, echec=0, nombreMots=1, numeroMot=0;
  long longueurChaine=0;
  char* motSecret = NULL;
  char* motDecouvert= NULL;
  
  //Ouverture fichier dictionnaire et recherche du motSecret
  FILE* dictionnaire = NULL;
  dictionnaire = fopen("dictionnaire_pendu.txt", "r");
  if (dictionnaire != NULL)
  {
        nombreMots=nombredemots(dictionnaire);
        numeroMot=nombreAleatoire(nombreMots);
        motpioche(dictionnaire, numeroMot, motSecret); 
        fclose(dictionnaire);
  }
  else
  {
        printf("Impossible d'ouvrir le fichier dictionnaire_pendu.txt");
  }
  
  //Initialiser et remplire motDecouvert
  longueurChaine=strlen(motSecret);
  motDecouvert=malloc(sizeof(char) * longueurChaine-1) ;
  for (i = 0 ;i< longueurChaine ;i++)
  {
      motDecouvert[i]='*';
  }
   motDecouvert[longueurChaine]='\0';

  //LE JEU
  printf("--------------------------Bienvenu sur le jeu du pendu--------------------------\n\n");
  nombreCoupsRestants=niveau();
  printf("Vous avez %i coups pour trouver le mot secret.\n",nombreCoupsRestants);
  i=nombreCoupsRestants;
  while(i>0)
  {
                                    printf("Quel est le mot secret?");
                                    asterix(motSecret, motDecouvert, longueurChaine);
                                    echec=nouvelleSaisie(motSecret, motDecouvert, longueurChaine);
                                    if(echec==0)
                                    {
                                        printf("Il vous reste %i coups pour trouver le mot secret.\n",--nombreCoupsRestants);
                                    }
                                    finir=gagnerPerdre(motSecret, motDecouvert, nombreCoupsRestants);
                                    if(finir==1)
                                    {break;}
                                    else
                                    {continue;} 
                                    i--;                 
  }
  
  free(motDecouvert);
  
  
  system("PAUSE");	
  return 0;
}


Les fonctions:
Code : C
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "headers.h"
#define TAILLE_MAX 1000

//Nombre de mots dans le dictionnaire
int nombredemots(FILE* dictionnaire)
{       
        int caractereActuel=0, nombreMots=0;
        rewind(dictionnaire);
        do
        {
             caractereActuel=fgetc(dictionnaire);
             if(caractereActuel=='\n')
             {
                                      nombreMots++;
             }
        }while(caractereActuel != EOF);
        return nombreMots;
}

//nombre aléatoire
long nombreAleatoire(long nombreMax)
{
    srand(time(NULL));
    return (rand() % nombreMax);
}

//Selection du motSecret
void motpioche(FILE* dictionnaire, int numeroMot, char motpioche[])
{
        int caractereActuel=0;
        rewind(dictionnaire);
        while(numeroMot>0)
        {
             caractereActuel=fgetc(dictionnaire);             
             if(caractereActuel=='\n')
             {
                                      numeroMot--;
             }
             
        }
        fgets(motpioche, TAILLE_MAX,dictionnaire);
        motpioche[strlen(motpioche)-1]='\0';
}

//Niveau de jeu
int niveau()
  {
      int difficulte=0, nombreCoupsRestants=0;
      printf("Quel difficulte voulez-vous? (1 pour facile, 2 pour moyen ou 3 pour difficile):");
      scanf("%i", &difficulte);
      while (getchar() != '\n');
      if(difficulte==1)
      {return nombreCoupsRestants=20;}
      else if(difficulte==2)
      {return nombreCoupsRestants=15;}
      else if (difficulte==3)
      {return nombreCoupsRestants=10;}
      else
      {printf("Erreur d'entree...relancez l'application");
      system("PAUSE");exit(1);}
  } 

//Alternative à scanf

char lirecaractere()
{
     char caractere=0;
     caractere=getchar();
     caractere=toupper(caractere);
     while(getchar() != '\n');
     return caractere;
}
//Asterix
void asterix(char motSecret[],char motDecouvert[], long longueurChaine)
{
                   int i=0;
                   for (i = 0 ;i< longueurChaine ;i++)
                   {
                                           printf("%c", motDecouvert[i]);
                   }
}




//Nouvel essai
int nouvelleSaisie(char* motSecret, char* motDecouvert, long longueurChaine)
{
     int i=0, perdu=0;
     char maLettre='a';
     printf("\nProposez une nouvelle lettre:");
     maLettre=lirecaractere();
     for(i=0;i<longueurChaine;i++)
     {
                                  if (motDecouvert[i]==maLettre)
                                  {
                                                               printf("Lettre deja proposee...\n");
                                                               return 0;
                                  }
                                  if (motSecret[i]==maLettre)
                                  {
                                                             motDecouvert[i]=maLettre;
                                  }
                                  else
                                  perdu++;
     }      
     if(perdu==longueurChaine)
     return 0;
     else 
     return 1;      
}


//Gagné ou perdu?!?

int gagnerPerdre(char* motSecret, char* motDecouvert, int nombreCoupsRestants)
{
    int resultat=0;
    if(strcmp(motDecouvert,motSecret)==0)
    {                                 
                                      printf("Vous avez decouvert le mot secret!\n");        
                                      resultat=1;
    }
    else if(nombreCoupsRestants==0)
    {
         
                                      printf("Vous avez perdu!!!\n");
                                      resultat=1;
    }        
    else 
    {
                                      resultat=0;
    }
    return resultat;
}


Et les headers:
Code : C
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#ifndef DEF_HEADERS.H
#define DEF_HEADERS.H
int nombredemots(FILE* dictionnaire);
long nombreAleatoire(long nombreMax);
void motpioche(FILE* dictionnaire, int numeroMot, char motSecret[]);
int niveau();
char lirecaractere();
void asterix(char motSecret[],char motDecouvert[], long longueurChaine);
int nouvelleSaisie(char* motSecret, char* motDecouvert, long longueurChaine);
int gagnerPerdre(char*motSecret, char* motDecouvert, int nombreCoupsRestants);






#endif
Hors ligne etrange02 # Posté le 22/07/2008 à 01:02:37
Pourquoi, il en faut une?
Avatar
Groupe : Membres
Dans ta fonction main, motSecret doit déjà être une chaîne (enlève aussi l'étoile) et cela ne pose aucun problème (j'ai encore mon code pour te dire) :
Code : C
1
char motSecret[100]="";


Ensuite, dans ta fonction motPioche, je te conseil de créer une autre chaîne :
Code : C
1
char secret[100] = "";

Grâce à cette chaîne tu peux récupérer un mot du dictionnaire avec fgets comme tu l'as fait (TAILLE_MAX vaut 100) sans oublier la suppression du \n comme tu l'as aussi fait (c'est pas génial ça ?). Ensuite tu copie les caractères présents dans secret dans motSecret et le tour est joué.

Mais (il y a toujours un mais), cette fois-ci, il n'y en a pas :p
Édité le 22/07/2008 à 01:06:42 par etrange02

:colere2: Pas de fautes d'orthographe s'il vous plaît et un peu de respect pour la syntaxe :colere2:
 
Hors ligne bjarni3000 # Posté le 22/07/2008 à 01:29:10
Groupe : Membres
YES!!! Bien vu merci énormément! :D

Faire une autre chaine dans la fonction n'est pas indispensable apparemment mais le tableau à l'initialisation oui. Je pensais faire un malloc plus loin mais vu que ça buggait je l'avais pas fait. Au tout cas merci parce que je cherchais l'erreur ailleurs, vers le strlen plutôt. Ca fonctionne enfin comme j'ai envie,que c'est beau: ni erreur à la compilation ni plantage!
Allez maintenant je vais pouvoir l'améliorer un peu ce pendu!!! ^^ Merci encore!
Hors ligne etrange02 # Posté le 22/07/2008 à 02:20:30
Pourquoi, il en faut une?
Avatar
Groupe : Membres
N'hésite pas non plus à me faire part des améliorations, ça fait toujours plaisir !

:colere2: Pas de fautes d'orthographe s'il vous plaît et un peu de respect pour la syntaxe :colere2:
 

Retour au forum "Langage C" ou à la liste des forums

Vous devez être inscrit pour pouvoir poster des messages

Changer de design | En savoir plus | Plan du site | Politique d'accessibilité | Règles | RSS tutoriels | RSS news
Édité par Simple IT SARL : Nous contacter | Notre blog | Revue de presse | Publicité

Y'a plus rien à lire, faut remonter maintenant !

Hébergement web - Correction de tutoriels - Créer un site
Vous souhaitez apparaître ici ? Contactez-nous.

Nombre de connectés 563 Zéros connectés | Requêtes SQL 9 requêtes | Temps de génération de la page : Total (SQL) 0.0239s (0.0085s)