IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

Pendu avec un fichier


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2016
    Messages
    109
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2016
    Messages : 109
    Par défaut Pendu avec un fichier
    Bonjour je suis en train de faire un pendu en C et j'ai déjà réalisé la première partie du code, ou une variable est une chaîne qui est le mot à trouver mais j'aimerais pouvoir le faire avec un fichier avec plusieurs mots.

    Voici la première partie du code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include <string.h>
     
     
     
    char lireCaractere()
    {
        char caractere=0;
        caractere = getchar();
        caractere = toupper(caractere);
     
        while(getchar() != '\n');
     
        return caractere;
     
    }
     
    int main()
    {
        int NB_COUP_MAX = 10;
        char const motSecre[]="BONJOUR";
        char motActuel[128]="*******";
        char maLettre=0;
        int lettreTrouvee = 0; // booléen 
        int j = 0;
        int longueur= strlen(motSecre);
        printf("Bienvenue sur le jeu du pendu ! \n ");
     
     
     
        while(strcmp(motSecre, motActuel) != 0 && NB_COUP_MAX > 0)
        {
            printf("Voici le mot actuel: %s, il vous reste %d \n", motActuel, NB_COUP_MAX);
            printf("Saisir une lettre: ");
            maLettre=lireCaractere();
            for(j=0 ; j<longueur ; j++){
                if(motSecre[j] == maLettre){
                    motActuel[j] = maLettre;
                    lettreTrouvee = 1;
                }
     
     
            }
     
            if(lettreTrouvee == 0){
                NB_COUP_MAX -= 1;   
            }
     
        }
        if(strcmp(motSecre, motActuel) == 0)
            printf("Félicitation vous avez trouvé le bon mot: %s ! \n", motSecre);
        else
            printf("Vous avez perdu, le nombre de tentatives a été atteint ! \n");
     
        return 0;
    J'ai ensuite fait une deuxième partie qui consiste à compter le nombre de lignes du fichier et à stocker cette valeur dans une variable compteur.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include <string.h>
     
    int main(void)
    {   
        int caractere = 0;
        int compteur = 0;
        FILE *fichier = fopen("test", "r");
     
        if(fichier != NULL)
        {
     
        do
        {
            caractere=fgetc(fichier);
            if(caractere == '\n')
                compteur++;
     
        }while(caractere != EOF);
        printf("Compteur : %d\n",compteur );
        rewind(fichier);
     
        fclose(fichier);
     
    }
     
     
        return 0;
    }
    J'utilise rewind pour revenir à la position de départ du fichier, le soucis c'est que j'aimerais donc ensuite pouvoir saisir aléatoirement un nombre entre 1 et le compteur et ensuite me déplacer dans mon fichier par LIGNE et stocker ce mot dans une chaîne mais je vois pas comment me déplacer par ligne.

    J'ai vu qu'il y avait la fonction fseek mais elle permet de se déplacer par caractère. Ou faut-il utiliser la fonction fgets ? mais comment l'utiliser avec le compteur ?

    Enfin pour générer un nombre aléatoire on utilise la fonction rand du coup ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    int nombreAleatoire;
    nombreAleatoire = rand(1, compteur);
    ça donnerait ça ?

  2. #2
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    On lit une ligne avec fgets. Tu as choisi de faire deux passes sur le fichier mais tu peux alternativement placer son contenu dans une structure de données (par exemple un tableau de chaînes). Dans ton cas (exercice d'apprentissage) c'est kif-kif mais c'est en règle général plus propre de ne pas multiplier les opérations d'entrée-sortie. D'autant plus qu'il y a des entrées qui ne se « rembobinent » pas (pipe, flux réseau...).

    rand ne s'invoque pas de cette manière. Tu trouveras les man de la bibliothèque standard par exemple ici.

  3. #3
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2016
    Messages
    109
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2016
    Messages : 109
    Par défaut Re
    Merci pour ta réponse !

    Que veut-tu dire par multiplier les opérations d'entrées-sorties ?

    Quand tu dis stocker les valeurs dans un tableau de chaîne tu veux dire les mots du fichier ?

    D'accord pour fgets, je m'en doutais un peu, mais comment l'utiliser avec le nombre généré aléatoirement du coup ?

    Je vais regarder ça pour le rand .

  4. #4
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    Citation Envoyé par drakop Voir le message
    Que veut-tu dire par multiplier les opérations d'entrées-sorties ?
    Ton algo consiste à parcourir le fichier texte une première fois afin de déterminer le nombre de lignes qui y sont contenues. Cela t'oblige à considérer toutes les informations du fichier, puisqu'il faut bien vérifier chaque caractère jusqu'à la fin du fichier (fgets le fait pour toi, mais c'est ce qui est fait en interne car il faut bien détecter '\n', '\r' et "\r\n"...).

    Donc quitte à tout lire, autant en profiter pour stocker les infos et ne faire qu'une passe, plutôt que de rewind et relire le fichier une seconde fois.


    Citation Envoyé par drakop Voir le message
    Quand tu dis stocker les valeurs dans un tableau de chaîne tu veux dire les mots du fichier ?
    Je ne sais pas comment ton fichier est structuré, j'imagine un mot par ligne ? Alors tu peux copier le contenu de chaque ligne (moins le ou les caractère(s) de fin de ligne) dans un élément du tableau. Si tu n'as pas encore vu l'allocation dynamique (malloc et compagnie...), commence avec un tableau statique d'une taille telle qu'aucun fichier d'entrée ne contiendra jamais plus de lignes, par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const char *words[4096]; // room for no more than 4096 words

    Citation Envoyé par drakop Voir le message
    D'accord pour fgets, je m'en doutais un peu, mais comment l'utiliser avec le nombre généré aléatoirement du coup ?
    Indices : un compteur, une valeur limite, un buffer de destination, une boucle... Lis bien la page de manuel de fgets surtout, il y a des pièges.

  5. #5
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2016
    Messages
    109
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2016
    Messages : 109
    Par défaut re
    Re!

    J'ai essayé de regarder mon algo, pour stocker les valeurs du fichier dans un tableau mais sans succès.

    La fonction fgets ne permet-elle pas de stocker ces mots dans un tableau de chaîne ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include <string.h>
     
    #define MAX_SIZE 4096
    int main(void)
    {
        FILE *fichier = fopen("test", "r");
        char word[MAX_SIZE];
        int compteur = 0;
        int i = 0;
     
     
     
        if(fichier != NULL)
        {
            while(fgets(word, MAX_SIZE, fichier) != NULL)
            {
                printf("%s \n",word );
                compteur++;
                i++;
     
            }
     
     
     
            printf("%d\n",compteur);
            printf("%s \n",word);
     
     
     
            fclose(fichier);
     
     
     
        }
        return 0;
    }
    Au vu de la compilation de mon code je dirai que ça stocke un mot par mot.

    Le pb étant j'ai l'impression que mon tableau est un tableau de char du coup mais pas de chaîne.

    Mais du coup je sais pas trop comment faire :/

    D'ailleurs je me suis dit que je devais peut-être mettre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     char *word[MAX_SIZE];
    
    Mais j'ai une erreur : 
    
    
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    123456789
     
    testFichier2.c: In function ‘main’:
    testFichier2.c:18:15: warning: passing argument 1 of ‘fgets’ from incompatible pointer type [-Wincompatible-pointer-types]
       while(fgets(word, MAX_SIZE, fichier) != NULL)
                   ^
    In file included from testFichier2.c:1:0:
    /usr/include/stdio.h:622:14: note: expected ‘char * restrict’ but argument is of type ‘char **’
     extern char *fgets (char *__restrict __s, int __n, FILE *__restrict __stream)
                  ^

  6. #6
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    Oui alors ce n'était pas très malin de ma part de te conseiller de ne pas faire d'allocation dynamique et de te montrer en exemple la déclaration précédente qui fait appel à un char *, const de surcroît donc inutilisable dans ton cas...

    Je t'ai induit en erreur, une meilleure solution consisterait à déclarer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #define MAX_WORD_LEN 30
    #define MAX_WORD_SIZE (MAX_WORD_LEN + 2) // plus one char for '\n' from fgets(), plus another one for '\0'
    #define MAX_WORD_NUM 4096
     
    char words[MAX_WORD_NUM][MAX_WORD_SIZE]; // room for up to MAX_WORD_NUM words of up to MAX_WORD_LEN ASCII characters
    Et voici un exemple d'utilisation (j'ai absolument pas compilé ni testé ce code, mais l'idée y est ), on lit le fichier ligne par ligne et on rejette les mots trop longs (de longueur supérieure à une limite prédéterminée) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    unsigned int wnum = 0; // number of words read so far
    while (wnum < MAX_WORD_NUM && fgets(words[wnum], MAX_WORD_SIZE, f) != NULL) {
        const size_t word_len = strlen(words[wnum]);
     
        if (word_len < MAX_WORD_LEN + 1 || words[wnum][MAX_WORD_LEN] == '\n') {
            words[wnum][word_len - 1] = '\0'; // erasing '\n' char from string
            printf("[%4u] '%s'\n", words[wnum]);
            ++wnum;
        }
        else fprintf(stderr, "warning: dropped word beginning with '%s': too long\n", words[wnum]);
    }
     
    if (wnum < MAX_WORD_NUM) {
        if (feof(f))
            printf("read %u words from file\n", wnum);
        else if (ferror(f)) {
            fprintf(stderr, "error: unknown I/O error occurred\n");
            exit(EXIT_FAILURE);
        }
    }
    else fprintf(stderr, "warning: read a maximum of %d words, dropping rest of file\n", MAX_WORD_NUM);

Discussions similaires

  1. [Avis] un Pendu avec ouverture fichier pour les mots :)
    Par arsenik360 dans le forum Débuter
    Réponses: 4
    Dernier message: 14/04/2011, 12h29
  2. Mise à jour d'une table avec un fichier csv
    Par blackangel dans le forum PostgreSQL
    Réponses: 4
    Dernier message: 26/05/2005, 14h46
  3. Réponses: 2
    Dernier message: 26/07/2004, 13h34
  4. [linux][gcc] Comment travaille t-on avec plusieurs fichiers?
    Par kaygee dans le forum Autres éditeurs
    Réponses: 2
    Dernier message: 02/04/2004, 17h48
  5. Problème avec les fichiers .JPG
    Par cprogil dans le forum Langage
    Réponses: 5
    Dernier message: 10/06/2003, 15h44

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo