Cmt lire un mot ds un fichier et l envoyer vers un char[]?

Fermé
astengo Messages postés 8 Date d'inscription dimanche 24 août 2014 Statut Membre Dernière intervention 29 avril 2015 - 7 sept. 2014 à 19:56
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 - 8 sept. 2014 à 11:40
Bonjour,

Je suis entrain d'essayer de programmer un pendu, avec une bibliothèque de mots dans un fichier a part. Le problème est avec ce bibliothèque extérieure au programme.

J'ai testé le jeu avec un mot que je rentre directement dans le main, il marche. Je tente maintenant d'intégrer une bibliothèque, c'est le fichier "dico.txt". J'arrive pas a mettre un mot de ce fichier dans le tableau de char motSecret.
Vers la fin de la fonction choisitMot j'ai l'instruction suivante: *motSecret=caractereActuel; le premier est un char*, le second un int, il faut faire une conversion ou l'ordi comprend cette ligne?
Ensuite je suis pas sûr de bien me positionner dans le fichier.
L IDE commence l'exécution du programme puis renvoie un nombre pas catholique.
J'espère que le programme est compréhensible malgré le nombre de variables déclarées.
Je ne mets pas le contenu des fonctions du jeu car il tourne bien.
Le probleme est -probablement- dans la fonction choisitMot.

JB.

le main.c:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "pendu.h"

int main()
{
    char maLettre = 0, *motSecret = 0;
    char motCache[27] = {0};
    int nbVies = 4, trouveLettre=2, gagner=0, qttMots;

    // choix du mot parmis ceux du dico:
    srand(time(NULL));
    qttMots = nbMots();

    choisitMot(qttMots, motSecret);

    // le mot est choisi le jeu peut demarer:
    printf("Bienvenue dans le pendu !\n\n");

    initMotCache(motSecret, motCache); // Transforme le motSecret en mot a etoiles.

    while(nbVies > 0 && gagner == 0)
    {
        printf("Il vous reste %d coups a jouer\n", nbVies);
        printf("Quel est le mot secret ? ");
        printf("%s\n", motCache);
        printf("Proposez une lettre : ");
        maLettre = lireCaractere(); // apres presentation du mot (a etoiles) l'utilisateur entre une lettre
        printf("\n");

        trouveLettre = presence(motSecret, maLettre, motCache); /* cette fonction
                                        renvoit un booleen sur la lettre entree et
                                        permet d afficher les lettres trouvees ds le
                                        motCache. */
        if (trouveLettre == 0) /* La la boucle regarde si l'utilisateur a entrer une
                                    lettre presente ds le nom ou pas*/
        {
            nbVies--;
        }
        gagner= gagne(motSecret, motCache); // Booleen qui regarde si le mot a ete trouve.
    }

    if(gagner == 0)
    {
        printf("\n*** PENDU ***\nLe mot secret etait %s\n\n\n\n\n\n", motSecret);
    }
    else
    {
        printf("\n*** BRAVO ***\nLe mot secret etait bien %s\n\n\n\n\n\n", motSecret);
    }

    return 0;
}



le pendu.h:
#ifndef DEF_PENDU

#define DEF_PENDU
#include <stdio.h>

// le jeu en lui-meme
char lireCaractere();
int nbCaracteres(const char* mot);
void initMotCache(const char* mot, char* motMasque);
int presence(const char* mot,const char* lettre, char*motMasque);
int gagne(const char* mot, const char* motMasque);

// le dico
int nbMots(); // compte le nb de mots total ds le dico
int choisitMot(const int nbMots, char* motSecret);

#endif // DEF_PENDU



le pendu.c:
int nbMots()
{
    FILE* fichier = NULL;
    int nb=1, caractereActuel=0 ;
    fichier = fopen("dico.txt", "r");

    if (fichier != NULL)
    {
        do
        {
            caractereActuel = fgetc(fichier);
            if (caractereActuel == '\n')
            {
                nb++;
            }
        }while(caractereActuel != EOF);
        fclose(fichier);
    }
    else
    {
        return 0;
    }

    return nb;
}





int choisitMot(const int nbMots, char* motSecret)
{
    int ligne=0, caractereActuel=0, chercheEntree=0, nbLettres=0, i=0 ;
    ligne = (rand() % nbMots) + 1 ;

    FILE* fichier = NULL;
    fichier = fopen("dico.txt", "r");
    if (fichier != NULL)
    {
       do // je vais a la bonne ligne pour lire le mot choisi par le pgm
       {
           caractereActuel = fgetc(fichier);
            if (caractereActuel == '\n')
            {
                chercheEntree++;
            }
        }while(chercheEntree < ligne);

        while (caractereActuel != '\n')// je compte le nombre de lettres dans le mot
        {
            caractereActuel = fgetc(fichier);
            nbLettres++;
        }

        // je remplis motSecret par les lettre du mot ecrit ds le dico
        fseek(fichier, -nbLettres, SEEK_CUR);
        motSecret = NULL;
        motSecret = malloc(nbLettres * sizeof(int));

        if(motSecret == NULL)
        {
            exit(0);
        }

        for (i=0; i<nbLettres; i++)
        {
            caractereActuel = fgetc(fichier);
            motSecret[i] = caractereActuel;
        }

       return 1;
    }
    else
    {
        return 0;
    }

}
A voir également:

2 réponses

fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
7 sept. 2014 à 20:18
Bonjour,

motSecret = NULL;
motSecret = malloc(nbLettres * sizeof(int));

Pourquoi mettre NULL dans motSecret et remettre juste derrière malloc() ? La première est superflue.
Sinon, tu fais une allocation dans motSecret qui est une copie de motSecret du main(). Dis autrement, à la fin de la fonction, motSecret vaut toujours NULL (puisque tu as fait char *motSecret=0; D'ailleurs, ça serait mieux de faire : =NULL que = 0.

Il faut donc passer par un double pointeur.
Corrige et dis-nous si le problème persiste.

Cdlt,
0
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
Modifié par [Dal] le 8/09/2014 à 11:46
Salut astengo,

Pour la malloc, fiddy a raison. Alternativement, puisque tu déclares
char motCache[27] = {0};
ce qui fixe une limite à la longueur du mot à un maximum de 26 lettres, tu pourrais faire
char motSecret[27] = {0};
et t'éviter les doubles pointeurs et le malloc (en vérifiant que les mots n'excèdent pas cette limite).

Sinon, il y a de nombreux autres problèmes.

1.

Tu n'as pas mis l'implémentation de la fonction presence, cependant son prototype est :

int presence(const char* mot,const char* lettre, char*motMasque);


dans main, tu l'appelles ainsi :

trouveLettre = presence(motSecret, maLettre, motCache);


alors que maLettre est un char (et pas un pointeur sur char)

s'il s'agit bien d'une lettre, ton prototype ne devrait-il pas être :
int presence(const char* mot, const char lettre, char*motMasque);


Dans ton main.c, tu utilises time(), il te faudrait un
#include <time.h>


2.

Dans NbMots, ton compteur devrait être initialisé à 0, pas à un.

Dans choisitMot, tu fais
ligne = (rand() % nbMots) + 1 ;
, et donc, s'il y a 10 mots, ligne va valoir de 1 à 10.

Par conséquent, ton bloc :

 do // je vais a la bonne ligne pour lire le mot choisi par le pgm
       {
           caractereActuel = fgetc(fichier);
            if (caractereActuel == '\n')
            {
                chercheEntree++;
            }
        }while(chercheEntree < ligne); 


n'est pas adapté, tu devrais faire un
while(chercheEntree < ligne)
, autrement, en cherchant la ligne 1, tu tomberas sur la ligne 2.

Le suivant :

while (caractereActuel != '\n')// je compte le nombre de lettres dans le mot    
        {
            caractereActuel = fgetc(fichier);
            nbLettres++;
        }


devrait en revanche être un do / while. Sinon, lorsque tu arrives au while, caractereActuel vaut déjà '\n' car c'est là que c'est arrêtée ta boucle précédente, et aucun caractère n'est consommé par la nouvelle boucle (nbLettres restant alors à 0).

Enfin, à la fin de la boucle for tu copies aussi le '\n' qui vient du fichier, tu devrais l'écraser et le remplacer par '\0' pour terminer la chaîne à cet endroit.

Donc, ajouter un
motSecret[nbLettres - 1] = '\0';
après ta boucle.

Tu devrais faire un
fclose(fichier);
à la fin de l'implémentation de
choisitMot
.


Dal
0