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 :

erreur exercice allocation dynamique


Sujet :

C

  1. #1
    Candidat au Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Août 2016
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Août 2016
    Messages : 7
    Points : 4
    Points
    4
    Par défaut erreur exercice allocation dynamique
    Bonjour dans mon exercice je dois créer un jeu du pendu qui va chercher le mot au hasard dans un fichier. voilà mon code

    Mon main.c
    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
     
    int main()
    {
        char motSecret[100] = ""; //le mot à trouver
        hasardMot(&motSecret);
        int *lettreTrouve = NULL; //tableau boléen qui permet de savoir quelle lettre a été trouvée
        lettreTrouve = malloc(strlen(motSecret)*sizeof(int) );
        char lettre = 0; //lettre entré par l'utilisateur
        int vie = 10; //nombre de vie pour trouver le mot
        int gagne = 0; //1 si le jouer a gagné et 0 si le jouer n'a pas gagné
        int i = 0;
        for (i=0 ; i<strlen(motSecret); i++)
        {
            lettreTrouve[i] = 0;
        }
     
        printf("::: Bienvenu dans ce jeu du pendu :::\n");
        printf("Vous avez %d vies pour trouver le mot secret\n\n", vie);
     
        while (vie>0 && !gagner(lettreTrouve, motSecret))
        {
            gagne = 1;
            printf("Il vous reste %d vies\n", vie);
            afficheMot(motSecret, lettreTrouve);
            printf("Entrer une lettre : ");
            lettre = lireCaractere();
            if (!verificationLettre(motSecret, lettreTrouve, lettre))
            {
                vie--;
            }
            printf("\n");
        }
        free(lettreTrouve);
     
        if (gagner(&lettreTrouve, motSecret))
        {
            printf("Bravo, vous avez gagné !!!");
        }
        else
        {
            printf("C'est perdu, le mot à trouver était %s", motSecret);
        }
     
    return 0;
    }
    mon fonction.c
    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
    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    #include <time.h>
     
     
    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 afficheMot (char motCache[], int lettreTrouve[])
    {
     
        int i = 0;
        printf("Le mot à trouver : ");
        for (i ; i<strlen(motCache); i++)
        {
            if (lettreTrouve[i]==1)
            {
                printf("%c", motCache[i]);
            }
            else
            {
                printf("*");
            }
        }
        printf("\n");
     
    }
     
    int verificationLettre (char motCacher[], int lettreTrouve[], char lettre)
    {
        int i = 0;
        int bonneLettre = 0;
     
        for (i=0 ; i < strlen(motCacher) ; i++)
        {
            if (motCacher[i] == lettre)
            {
                lettreTrouve[i] = 1;
                bonneLettre = 1;
            }
        }
     
    return bonneLettre;
    }
     
    int gagner(int lettreTrouve[], char motSecret[])
    {
        int i = 0;
        int gagne = 1;
        for (i=0 ; i<strlen(motSecret) ; i++)
            {
                if (lettreTrouve[i] == 0)
                    gagne = 0;
            }
     
        return gagne;
    }
     
    void hasardMot (char *motSecret)
    {
        int nbr_ligne = 0;
        int nbr_mots = 0;
        int i = 0;
        FILE *fichier = NULL;
        srand(time(NULL));
     
        //ouverture du fichier
        fichier = fopen("dico", "r");
     
        //verification ouverture fichier
        if(fichier != NULL)
        {
            printf("fichier ouvert\n\n");
            fscanf(fichier, "%d", &nbr_mots);
            nbr_ligne =(rand()%(nbr_mots-1)+1);
            for (i=0 ; i<nbr_ligne ; i++)
            {
                fscanf(fichier, "%s", motSecret);
            }
            motSecret[strlen(motSecret)]='\0';
            fclose(fichier);
        }
        else
        {
            printf("Impossible d'ouvrir le fichier dico");
        }
    }
    Le problème c'est que même si l'utilisateur trouve le mot le programme affiche perdu. j'ai cherché et faire différent essai mais je n'arrive pas à regler le problème. Merci d'avance

  2. #2
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2010
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2010
    Messages : 38
    Points : 79
    Points
    79
    Par défaut
    Rapidement car je suis sur mon téléphone. Fait attention à la libération de ce que tu alloues dynamiquement. Ensuite il faut comprendre ce que signifie &lettreTrouve, lettreTrouve et *lettreTrouve.

    Sinon un debugger et/ou des printf bien placés devraient t'aider.

  3. #3
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 565
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 565
    Points : 7 642
    Points
    7 642
    Par défaut
    Bonjour,

    Dans ton main.c, regarde la chronologie des lignes 37 et 39.

  4. #4
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 684
    Points : 30 973
    Points
    30 973
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par drsky Voir le message
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    motSecret[strlen(motSecret)]='\0';
    Bonjour

    Ce genre d'instruction, soit ça t'envoie droit dans le mur, soit ça fonctionne mais dans ce cas elle ne sert à rien. En effet, si tu veux mettre un '\0' dans ta chaine, c'est qu'à priori elle n'en contient pas (d'ailleurs dans ce cas, on n'a plus le droit de parler de "chaine").
    Mais la fonction strlen(), qui boucle sur chaque caractère de la chaine pour les compter ; à ton avis, sur quoi se base-t-elle pour s'arrêter de boucler ????

    Mais bon, ici comme la chaine a été remplie via un fscanf("%s"), il se trouve qu'elle contient bien un '\0' donc ça fonctionne mais ça ne fait rien de plus que de mettre un '\0' là où il y en a déjà un.

    Citation Envoyé par drsky Voir le message
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    char motSecret[100] = ""; //le mot à trouver
    hasardMot(&motSecret);
    
    void hasardMot (char *motSecret)
    {
        ...
    }
    Raté, le nom d'une chaine étant déjà un pointeur, on ne met pas de "&" devant. D'ailleurs tu le savais puisque ici fscanf(fichier, "%s", motSecret) tu n'as pas mis de "&"...

    Ceci n'était pas une liste exhaustive des erreurs mais c'est un pas vers la solution. Pour le reste, Sun.Wu.Kong t'a donné un bon conseil: rajoute des printf() aux évènements que tu veux vérifier...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  5. #5
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2010
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2010
    Messages : 38
    Points : 79
    Points
    79
    Par défaut
    Pour ma part, autre chose m'étonne (mais c'est parce que j'ai connu le temps de la place en mémoire limitée).

    Ce n'est pas une erreur en soit mais ton tableau lettreTrouve est composé de int. Pour un mot de 3 lettres, tu utilises 12 octets en mémoire. J'aurais plutôt utilisé un bool.

  6. #6
    Candidat au Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Août 2016
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Août 2016
    Messages : 7
    Points : 4
    Points
    4
    Par défaut
    Merci à tous, effectivement j'ai encore du mal à gérer les pointeurs. Je ne connais pas encore la variable bool je vais me renseigner.

    du coup l'erreur était dans la fonction gagner : for (i=0 ; i<(strlen(motSecret)-1) ; i++) .

    je ne comprend pas trop en faite j'ai remarqué en faisant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    //test
        printf("%s\n", motSecret);
        for (i=0; i < 20; i++)
            printf("%d", lettreTrouve[i]);
    Mon tableau lettreTrouve contient toujours un 0 en trop, si j'ai un mot de 5 lettre il contient 6 zero. je ne comprend pas trop pourquoi si vous pouvez m'éclairer une dernière fois. Merci à tous

  7. #7
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 684
    Points : 30 973
    Points
    30 973
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Sun.Wu.Kong Voir le message
    J'aurais plutôt utilisé un bool.
    Le bool c'est du C++. Je ne sais pas s'il a été rajouté dans les dernières normes du C (j'ai un peu décroché) mais au temps de la mémoire limitée, c'est certain qu'il n'existait pas. A cette époque, tu aurais plutôt utilisé les masques de bits...

    Citation Envoyé par drsky Voir le message
    du coup l'erreur était dans la fonction gagner : for (i=0 ; i<(strlen(motSecret)-1) ; i++) .

    je ne comprend pas trop en faite j'ai remarqué en faisant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    //test
        printf("%s\n", motSecret);
        for (i=0; i < 20; i++)
            printf("%d", lettreTrouve[i]);
    Mon tableau lettreTrouve contient toujours un 0 en trop, si j'ai un mot de 5 lettre il contient 6 zero. je ne comprend pas trop pourquoi si vous pouvez m'éclairer une dernière fois. Merci à tous
    Grave erreur, tu n'as pas trouvé la cause du problème mais tu as masqué son effet. Parce que dans la logique, si ton mot à trouver contient 5 lettres, tu es bel et bien obligé de boucler de 0 à 5.

    D'ailleurs, pour info, j'ai récupéré ton code initial (celui de ton premier post), corrigé les erreurs de "&" inutiles (il y en a 2), du free() qui n'est pas à la bonne place (cf post de dalfab) et au final ton code fonctionne parfaitement. Donc non seulement tu avais fait un code correct mais en plus, en le modifiant comme tu l'as fait, tu l'as dégradé.

    Voici mon (ton) code
    Code c : 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
    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
    140
    141
    142
    143
    144
    145
    146
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    #include <time.h>
     
     
    char lireCaractere()
    {
        char caractere = 0;
        caractere = getchar(); // On lit le premier caractère
     
        // On lit les autres caractères mémorisés un à un jusqu'au \n (pour les effacer)
        while (getchar() != '\n') ;
     
         return toupper(caractere); // On retourne le caractère lu en majuscules
    }
     
    void afficheMot (char motCache[], int lettreTrouve[])
    {
        int i;
        printf("Le mot à trouver : ");
        for (i=0 ; i<strlen(motCache); i++)
        {
            if (lettreTrouve[i]==1)
            {
                printf("%c", motCache[i]);
            }
            else
            {
                printf("*");
            }
        }
        printf("\n");
     
    }
     
    int verificationLettre (char motCacher[], int lettreTrouve[], char lettre)
    {
        int i = 0;
        int bonneLettre = 0;
        printf("lettre=%c\n", lettre);
     
        for (i=0 ; i < strlen(motCacher) ; i++)
        {
            if (motCacher[i] == lettre)
            {
                lettreTrouve[i] = 1;
                bonneLettre = 1;
            }
        }
     
        return bonneLettre;
    }
     
    int gagner(int lettreTrouve[], char motSecret[])
    {
        int i = 0;
        int gagne = 1;
        for (i=0 ; i<strlen(motSecret) ; i++)
            {
                if (lettreTrouve[i] == 0)
                    gagne = 0;
            }
     
        return gagne;
    }
     
     
    void hasardMot (char *motSecret)
    {
        int nbr_ligne = 0;
        int nbr_mots = 0;
        int i = 0;
        FILE *fichier = NULL;
        srand(time(NULL));
     
        //ouverture du fichier
        fichier = fopen("dico", "r");
     
        //verification ouverture fichier
        if(fichier != NULL)
        {
            printf("fichier ouvert\n\n");
            fscanf(fichier, "%d", &nbr_mots);
            nbr_ligne =(rand()%(nbr_mots-1)+1);
            for (i=0 ; i<nbr_ligne ; i++)
            {
                fscanf(fichier, "%s", motSecret);
            }
            fclose(fichier);
    	printf("[%s]\n", motSecret);
        }
        else
        {
            printf("Impossible d'ouvrir le fichier dico");
        }
    }
     
    int main()
    {
        char motSecret[100] = ""; //le mot à trouver
        hasardMot(motSecret);
        int *lettreTrouve = NULL; //tableau boléen qui permet de savoir quelle lettre a été trouvée
        lettreTrouve = malloc(strlen(motSecret)*sizeof(int) );
        char lettre = 0; //lettre entré par l'utilisateur
        int vie = 10; //nombre de vie pour trouver le mot
        int gagne = 0; //1 si le jouer a gagné et 0 si le jouer n'a pas gagné
        int i = 0;
        for (i=0 ; i<strlen(motSecret); i++)
        {
            lettreTrouve[i] = 0;
        }
     
        printf("::: Bienvenu dans ce jeu du pendu :::\n");
        printf("Vous avez %d vies pour trouver le mot secret\n\n", vie);
     
        while (vie>0 && !gagner(lettreTrouve, motSecret))
        {
    		for (i=0; i < strlen(motSecret); i++)
    			printf("%d ", lettreTrouve[i]);
    		printf("\n");
            gagne = 1;
            printf("Il vous reste %d vies\n", vie);
            afficheMot(motSecret, lettreTrouve);
            printf("Entrer une lettre : ");
            lettre = lireCaractere();
            if (!verificationLettre(motSecret, lettreTrouve, lettre))
            {
                vie--;
            }
            printf("\n");
        }
     
        if (gagner(lettreTrouve, motSecret))
        {
            printf("Bravo, vous avez gagné !!!");
        }
        else
        {
            printf("C'est perdu, le mot à trouver était %s", motSecret);
        }
        free(lettreTrouve);
     
    return 0;
    }
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  8. #8
    Membre chevronné Avatar de Ehonn
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    788
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 788
    Points : 2 160
    Points
    2 160
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Le bool c'est du C++. Je ne sais pas s'il a été rajouté dans les dernières normes du C (j'ai un peu décroché) mais au temps de la mémoire limitée, c'est certain qu'il n'existait pas.
    C99 avec #include <stdbool.h>.

Discussions similaires

  1. erreur d'allocation dynamique
    Par Lordryder dans le forum Débuter
    Réponses: 5
    Dernier message: 18/04/2012, 13h28
  2. Gestion des erreurs, allocation dynamique
    Par mach1 dans le forum C
    Réponses: 11
    Dernier message: 02/05/2010, 19h19
  3. probleme dans un exercice d'allocation dynamique
    Par Msakeni dans le forum Débuter
    Réponses: 4
    Dernier message: 26/02/2009, 01h55
  4. C++, erreur d'allocation dynamique de mémoire
    Par YuGiOhJCJ dans le forum C++
    Réponses: 8
    Dernier message: 20/02/2009, 11h51
  5. Erreur d'allocation dynamique de tableaux
    Par lclclc dans le forum Fortran
    Réponses: 1
    Dernier message: 02/04/2008, 15h10

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