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 :

TP pendu en C.(segmentation fault) aidez moi.


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Décembre 2010
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Décembre 2010
    Messages : 24
    Par défaut TP pendu en C.(segmentation fault) aidez moi.
    Bonjour ceci est mon 1er message sur ce forum et je suis novice en programmation, dans le cadre de ma formation on m'a demandé de réaliser un pendu en C, la compilation se passe à merveille et malheureusement à l'exécution au bout de quelques secondes windows 7 coupe mon programme. (je présume une de ces fameuses "segmentation fault" mais je n'arrive pas à trouver son origine. J'ai indenté et commenté mon code de manière à ce qu'il soit le plus lisible possible, merci d'avance pour vôtre aide.

    PS : Je sais qu'il y'a des milliers d'algos de pendus en C sur le net mais je veux pas copier-coller, je veux comprendre pourquoi le mien ne marche pas.

    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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include <string.h>
     
    int Iwin(char shadowTab[], char motSecret[]);
    char lireCaractere();
    int chercheLettre(int boolTab[] , char motSecret[],char lettre);
    char retourneTableau(char shadowTab[] , char motSecret[], char boolTab[] );
     
     
    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'à l'\n
        while (getchar() != '\n') ;
     
        return caractere; // On retourne le premier caractère qu'on a lu
    }
     
     
    int Iwin(char shadowTab[], char motSecret[])
    {
        int i = 0;
        int value = 0;
        for(i=0; motSecret[i] != '\0'; i++)
        {
            value =1;
            if(motSecret[i] != shadowTab[i])
            value =0;
        }
        return value;
    }
     
    int chercheLettre(int boolTab[] , char motSecret[],char lettre)
    {
        int i =0;
        for(i=0; (motSecret[i] != '\0'); i++)
        {
            if(motSecret[i]== lettre)
            boolTab[i]= 1;
            else
            boolTab[i]= 0;
        }
        return boolTab;
    }
     
     
    char retourneTableau(char shadowTab[] , char motSecret[], char boolTab[] )
    {
        int i =0;
        while(motSecret[i] !='\0')
        {
            if(boolTab[i]==1) //si boolTab est à 1 on révèle une lettre au joueur.
            shadowTab[i]=motSecret[i];
            else
            shadowTab[i]='*';
            i++;
        }
         return shadowTab;
    }
     
     
    int main()
    {
        char motSecret[20]="ROUGE"; //mot secret du pendu, invisible au joueur.
        char shadowTab[20]="*****"; //tableau affiché à l'écran du joueur
        int boolTab[20] = {0}; // tableau booléen qui servira à réveler ou non les lettres sur le tableau affiché à l'écran du joueur.
        int compteCoups = 10;
        int winner = 0;
        char lettre;
     
        while((compteCoups !=0) && (winner !=1) )
        {
     
            printf("le mot secret est %s \n",shadowTab);
            printf("Il vous reste %d Coups saisissez une lettre \n", compteCoups);
            compteCoups--;
            lettre = lireCaractere();
            boolTab[20] = chercheLettre(boolTab,motSecret,lettre);
            shadowTab[20] = retourneTableau(shadowTab, motSecret, boolTab);
            winner = Iwin(shadowTab[20],motSecret);
     
        }
     
        if(winner == 1)shadowTab
        {
            printf("c'est win");
        }
        else
        {
            printf("c'est loose");
        }
     
        return 0;
    }

  2. #2
    Membre éprouvé

    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2008
    Messages
    39
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Février 2008
    Messages : 39
    Par défaut
    Bonjour,

    C'est toujours assez compliqué à déterminer donc je ne peux pour le moment que te donner des pistes. J'ai un doute sur la déclaration suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
     
    char motSecret[20]="ROUGE";
    J'aurais tendance à l'écrire plutot (même si ta solution marche peut-être):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
     
    char motSecret[20];
    strcpy(motSecret,"ROUGE");
    De cette façon tu as automatiquement le '\0' qui symbolise la fin de chaine. Même remarque pour shadowtab.

    Ensuite tu as également un problème avec les fonctions suivantes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
     
    boolTab[20] = chercheLettre(boolTab,motSecret,lettre);
    shadowTab[20] = retourneTableau(shadowTab, motSecret, boolTab);
    Je suis d'ailleurs surpris que la compile passe là dessus. Si on prend la fonction chercheLettre, elle est censée retourner un int alors que tu retournes boolTab qui est un int []. Pareil pour la fonction retourneTableau. Et tu mets le résultat dans la case 20 des tableaux qui n'existe pas puisqu'un tableau de 20 cases a des indices de 0 à 19.

    Il y a là une erreur à mon avis, il faut que tu détermine ce que tu veux faire mais ces deux fonctions ne doivent pas donner le résultat escompté en l'état.

    EDIT : Ah mon avis, tu peux déclarer le retour de ces deux fonctions en void et modifier les valeurs du tableau dans les fonctions. Et du coup, tu peux supprimer le return.

    Ce qui m'amène à une autre remarque, tu n'initialises pas un tableau entier en faisant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
     
    int boolTab[20] = {0};
    Ton initialisation devrait plutôt s'écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
     
    int boolTab[20] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
    Voila, ce sont quelques pistes de problèmes potentiel de mémoire. Je n'ai pas regardé pour le moment si ton programme fait bien ce qu'il devrait, je pense qu'il faudrait déjà corriger ces erreurs.

    Bonne journée,

    Aldiemus

  3. #3
    Membre très actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2010
    Messages
    254
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2010
    Messages : 254
    Par défaut
    Outils de debug
    Le meilleur ami du développeur. Ça devrait te donner au moins l'endroit où ton programme plante.

    Regarde aussi un autre programme appelé gdb. Ça te permet d'analyser ton programme pas par pas.

    A partir de la essaye de comprendre d'où vient le problème.

    Rappelle toi si un programme fait une segmentation fault, c'est qu'il écrit dans un espace mémoire non alloué.

  4. #4
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Par défaut
    De cette façon tu as automatiquement le '\0' qui symbolise la fin de chaine. Même remarque pour shadowtab.
    A la fin de toute chaine littérale, un '\0' est automatiquement rajouté.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char motSecret[20]="ROUGE";
    est donc correct. La chaine ici se compose de : ROUGE\0

    J'ai pas analysé le code, juste survolé, mais je vois quelques choses étranges :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    boolTab[20] = chercheLettre(boolTab,motSecret,lettre);
    shadowTab[20] = retourneTableau(shadowTab, motSecret, boolTab);
    Je ne comprends pas ce que ce code est censé faire. En tout cas, tu accèdes en dehors des tableaux. Crash possible (peu probable, mais ça reste de toute façon un bug).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    winner = Iwin(shadowTab[20],motSecret);
    Tu envoies une valeur entière (de valeur indéterminée et de type char) alors que le premier paramètre de la fonction attend un pointeur. Crash assuré dès l'accès en mémoire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if(motSecret[ i ] != shadowTab[ i ] )
    Dans quelques fonctions, tu renvoies un type différent de celui attendu :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int chercheLettre(int boolTab[] , char motSecret[],char lettre)
    {
    (...)
       return boolTab;
    }
    Même chose dans la fonction qui suit.

    Le compilateur, s'il est bien réglé, doit absolument te donner une montagne de warnings.

  5. #5
    Membre très actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2010
    Messages
    254
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2010
    Messages : 254
    Par défaut
    Pour continuer sur cette lancée:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    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'à l'\n
        while (getchar() != '\n') ;
     
        return caractere; // On retourne le premier caractère qu'on a lu
    }
    Que fait ce while içi ? C'est une abberration vu que tu ne stock pas les caractères. et au passage :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     while (getchar() != '\n') ;
    Pourrait être remplacé par un fgets.

  6. #6
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Par défaut
    Que fait ce while içi ? C'est une abberration vu que tu ne stock pas les caractères. et au passage :
    Je pense que c'est simplement pour vider le buffer clavier après le getchar en début de fonction.
    Il y a une fonction très pratique dans la FAQ : http://c.developpez.com/faq/?page=cl...buffer_clavier

  7. #7
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Déjà en élevant le niveau de verbosité du compilateur, tu devrait pouvoir supprimer quelques erreurs potentielles. Pet être que dans le tas, il y a ton erreur

    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
    1>------ Début de la génération : Projet : Test, Configuration : Release Win32 ------
    1>Compilation en cours...
    1>Test.cpp
    1>.\Test.cpp(20) : warning C4244: '=' : conversion de 'int' en 'char', perte possible de données
    1>.\Test.cpp(21) : warning C4244: '=' : conversion de 'int' en 'char', perte possible de données
    1>.\Test.cpp(53) : error C2440: 'return' : impossible de convertir de 'int []' en 'int'
    1>        Aucun contexte dans lequel cette conversion est possible
    1>.\Test.cpp(68) : error C2440: 'return' : impossible de convertir de 'char []' en 'char'
    1>        Aucun contexte dans lequel cette conversion est possible
    1>.\Test.cpp(89) : error C2664: 'retourneTableau' : impossible de convertir le paramètre 3 de 'int [20]' en 'char []'
    1>        Les types pointés n'ont aucun rapport entre eux ; conversion nécessitant reinterpret_cast, cast de style C ou cast de style fonction
    1>.\Test.cpp(90) : error C2664: 'Iwin' : impossible de convertir le paramètre 1 de 'char' en 'char []'
    1>        La conversion d'un type intégral en type pointeur nécessite reinterpret_cast, un cast de style C ou un cast de style fonction
    1>.\Test.cpp(95) : error C2143: erreur de syntaxe : absence de ';' avant '{'
    1>.\Test.cpp(98) : error C2181: instruction else sans if correspondant non conforme
    Déjà, ceci ne devrait pas compiler :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    if(winner == 1)shadowTab
        {
            printf("c'est win");
        }
        else
        {
            printf("c'est loose");
        }
    Donc, est-ce que ce que tu nous montres est le code de ce que tu exécutes ?
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

Discussions similaires

  1. SDL : SVP aidez moi !!!
    Par adidmamah dans le forum OpenGL
    Réponses: 5
    Dernier message: 11/06/2004, 08h49
  2. [Kylix] Aidez-moi -> LIAISON SERIE 2 le retour
    Par Oyoboy dans le forum EDI
    Réponses: 1
    Dernier message: 28/05/2004, 10h48
  3. aidez moi à choisir
    Par lvdnono dans le forum DirectX
    Réponses: 4
    Dernier message: 13/05/2004, 08h20
  4. Réponses: 29
    Dernier message: 11/05/2004, 13h18
  5. Comment contrer la "segmentation fault" ?
    Par guillaume_pfr dans le forum C
    Réponses: 15
    Dernier message: 08/08/2003, 13h43

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