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 :

Ajout char dans adresse pointeur


Sujet :

C

  1. #1
    Membre éclairé Avatar de guitz
    Homme Profil pro
    Webdesigner
    Inscrit en
    Juillet 2006
    Messages
    717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Webdesigner

    Informations forums :
    Inscription : Juillet 2006
    Messages : 717
    Points : 741
    Points
    741
    Par défaut Ajout char dans adresse pointeur
    Bonsoir,

    Vraiment pas évident de se mettre au C quand on n'a codé que dans des languages de haut niveau tels que php, actionscript et javascript.
    Sacrée douche froide, mais je persévère

    Là je butte sur un pb de syntaxe : Comment allouer un caractère à l'index d'un pointeur typé chaîne de caractère ? J'ai tout essayé mais le programme plante, après la compilation, à l'ouverture de la console (il y a un printf ultérieure dans mon code).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    char lettreEntree = 'O', *tempMotSecret = NULL, motSecret[] = "MARRON";
    tempMotSecret = strchr(motSecret, lettreEntree); 
    //cette sous-chaine obtenue, qui initialement pourtant n'avait 
    //pas été typée en tableau (string), a donc pour valeur "ON" 
    tempMotSecret[0] = 'z';
    J'ai pourtant tou essayé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    *tempMotSecret[0] = 'z';
    *(tempMotSecret)[0] = 'z';
    ou encore

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    *(tempMotSecret[0]) = 'z';
    Mais rien n'y fait. Que dois-je modifier svp pour que ce programme ne plante pas ?

  2. #2
    Membre éclairé
    Avatar de Pouet_forever
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    671
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 671
    Points : 842
    Points
    842
    Par défaut
    Salut,

    Ton premier code est bon, normalement tu ne devrais pas avoir d'erreurs
    Normalement après ton strchr tempMotSecret vaut ON, et dès que tu lui affectes 'z' tempMotSecret vaut zN.

    Peut-être n'as-tu pas posté tout ton code et que tu problème vient d'ailleurs
    Plus tu pédales moins fort, moins t'avances plus vite.

  3. #3
    Membre chevronné
    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
    Points : 1 750
    Points
    1 750
    Par défaut
    Ce code marche très bien :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include <stdio.h>
    #include <string.h>
     
    int main(void)
    {
    	char lettreEntree = 'O', *tempMotSecret = NULL, motSecret[] = "MARRON";
    	tempMotSecret = strchr(motSecret, lettreEntree);
    	if (tempMotSecret != NULL)
    		*tempMotSecret = 'z';
    	printf("%s",motSecret);
    	return 0;
    }
    J'ai juste rajouté le test qui vérifie que tempMotSecret n'est pas NULL (sinon, ça crashe si la lettre n'est pas trouvée dans le mot).

    En l'état actuel de ton code, ça ne devrait pas crasher car 'O' est bien présent dans 'MARRON'. Si ça plante, le problème est donc ailleurs. Il faudrait que tu nous montres ton code entier pour voir d'où vient l'erreur.

  4. #4
    Membre éclairé Avatar de guitz
    Homme Profil pro
    Webdesigner
    Inscrit en
    Juillet 2006
    Messages
    717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Webdesigner

    Informations forums :
    Inscription : Juillet 2006
    Messages : 717
    Points : 741
    Points
    741
    Par défaut
    J'ai pensé que ça venait de cette ligne vu que qd je l'ôte, ça ne plante plus.

    Voici le code en entier qui consiste à réaliser le jeu du pendu en console :

    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include <time.h>
    #include <string.h>
    #include <ctype.h>
     
    char lireCaractere();
    void afficherMotMasque(char lettreEntree, char motSecret[], char* motMasque[]);
     
    int main(int argc, char *argv[]){
     
        printf("Bienvenu dans le pendu !\n\n\n");
     
        char motSecret[] = "MARRON", lettreEntree = lireCaractere();
        char* motMasque[7];
     
        afficherMotMasque(lettreEntree, motSecret, motMasque);
     
     
        return 0;
    }
     
    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 (pour les effacer)
        while (getchar() != '\n') ;
        return caractere; // On retourne le premier caractère qu'on a lu
     
    }
     
    void afficherMotMasque(char lettreEntree, char motSecret[], char* motMasque[]){
     
        //printf("lettre entree = %c    mot secret = %s", lettreEntree, motSecret);
     
        char *tempMotSecret = NULL;
        int indexLettreTrouvee, i = 0;
     
        // Si on a trouvé quelque chose
        do{
     
            if(i == 0){ //lors de la premiere lecture de la boucle...
                tempMotSecret = strchr(motSecret, lettreEntree);
            }else{
                tempMotSecret = strchr(tempMotSecret, lettreEntree);
            }
            indexLettreTrouvee = strlen(motSecret) - strlen(tempMotSecret);
            printf("index = %d\n", indexLettreTrouvee);
            printf("i = %d\n\n", i);
            tempMotSecret[0] = 'z'; //on supprime la lettre choisie par le joueur pour que la boucle suivante ne le comptabilise pas.
            i++;
     
        }while(tempMotSecret != NULL && i < 5);
     
    }
    Voilà c'est en cours de dev, l'algorythme n'est donc pas encore correctement rédigé. La fonction afficherMotMasque() sera sensée faire un printf du mot masqué avec les lettres trouvées visibles (ex : ****O*).

  5. #5
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Tu n'as pas tenu compte de la remarque de jeroman
    J'ai juste rajouté le test qui vérifie que tempMotSecret n'est pas NULL (sinon, ça crashe si la lettre n'est pas trouvée dans le mot).
    Lorsque tu appelle avec 'O' ta fonction afficherMotMasque(), il trouve le 'O' en position 4. Puis, il recommence la boucle do. Et là,strchr(tempMotSecret, lettreEntree); répond NULL, puisqu'il n'y a pas d'autre 'O'. En conséquence, strlen(tempMotSecret) plante !

    Accessoirement, au lieu de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    indexLettreTrouvee = strlen(motSecret) - strlen(tempMotSecret);
    il est plus simple d'écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    indexLettreTrouvee = tempMotSecret-motSecret;
    On pourrait avoir comme code (je suppose que le paramètre motMasque servira plus tard)

    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
    void afficherMotMasque(char lettreEntree, char motSecret[], char* motMasque[]){
        char *tempMotSecret = motSecret;
        int indexLettreTrouvee, i = 0;
        // Si on a trouvé quelque chose
        do{
            tempMotSecret = strchr(tempMotSecret, lettreEntree);
            if( tempMotSecret != NULL)
            {
              indexLettreTrouvee = tempMotSecret-motSecret;
              printf("index = %d\n", indexLettreTrouvee);
              printf("i = %d\n\n", i);
              *tempMotSecret = 'z'; //on supprime la lettre choisie par le joueur pour que la boucle suivante ne le comptabilise pas.
              i++;
            }
        }while(tempMotSecret != NULL && i < 5);
     
    }
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  6. #6
    Membre éclairé Avatar de guitz
    Homme Profil pro
    Webdesigner
    Inscrit en
    Juillet 2006
    Messages
    717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Webdesigner

    Informations forums :
    Inscription : Juillet 2006
    Messages : 717
    Points : 741
    Points
    741
    Par défaut
    Citation Envoyé par diogene Voir le message
    Lorsque tu appelle avec 'O' ta fonction afficherMotMasque(), il trouve le 'O' en position 4. Puis, il recommence la boucle do. Et là,strchr(tempMotSecret, lettreEntree); répond NULL, puisqu'il n'y a pas d'autre 'O'. En conséquence, strlen(tempMotSecret) plante !
    Oui Jeroman avait bien vu, mais c'est dans mon code ci-dessus

    et il ne devrait pas reboucler puisque j'ai mis dans ma condition :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    do{
            ...
        }while(tempMotSecret != NULL && i < 5);

  7. #7
    Membre éclairé
    Avatar de Pouet_forever
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    671
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 671
    Points : 842
    Points
    842
    Par défaut
    Hé bien si justement !
    Parce que tu appelles strlen avant d'avoir testé ta condition dans le while
    Et puis au premier tour de boucle, tempMotSecret est différent de NULL donc c'est normal que ça reboucle

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    do {
    	/* strchr */
    	indexLettreTrouvee = strlen(motSecret) - strlen(tempMotSecret);
    	[...]
    } while(tempMotSecret != NULL && i < 5);
    Plus tu pédales moins fort, moins t'avances plus vite.

  8. #8
    Membre éclairé Avatar de guitz
    Homme Profil pro
    Webdesigner
    Inscrit en
    Juillet 2006
    Messages
    717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Webdesigner

    Informations forums :
    Inscription : Juillet 2006
    Messages : 717
    Points : 741
    Points
    741
    Par défaut
    Mais oui suisje bêêêête ! Quel goujat je suis !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    tempMotSecret = strchr(motSecret, lettreEntree);
     
        do{
            indexLettreTrouvee = tempMotSecret-motSecret;
            printf("index = %d\n", indexLettreTrouvee);
            printf("i = %d\n\n", i);
            tempMotSecret[0] = '_'; //on supprime la lettre choisie par le joueur pour que la boucle suivante ne le comptabilise pas.
            tempMotSecret = strchr(tempMotSecret, lettreEntree);
            i++;
     
        }while(tempMotSecret != NULL && i < 5);
    Merci les gars, je suis tellement absorbé par les subtilités de typages de var, par le concept de pointeur qui est tout nouveau pour moi, etc, que je n'ai même pas vu cette grossière erreur d'algo.

    Je vous remercie encore une fois et je retourne ponto presto finir mon pendu

  9. #9
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Non : si le mot secret ne contient pas la lettre, le code plante

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     tempMotSecret = strchr(motSecret, lettreEntree);
     while(tempMotSecret != NULL && i < 5);
     {
         indexLettreTrouvee = tempMotSecret-motSecret;
         printf("index = %d\n", indexLettreTrouvee);
         printf("i = %d\n\n", i);
         tempMotSecret[0] = '_'; //on supprime la lettre choisie par le joueur pour que la boucle suivante ne le comptabilise pas.
         tempMotSecret = strchr(tempMotSecret, lettreEntree);
         i++; 
     }
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  10. #10
    Membre éclairé Avatar de guitz
    Homme Profil pro
    Webdesigner
    Inscrit en
    Juillet 2006
    Messages
    717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Webdesigner

    Informations forums :
    Inscription : Juillet 2006
    Messages : 717
    Points : 741
    Points
    741
    Par défaut
    Oui c'est vrai à la première lecture de la boucle, si l'utilisateur se trompe de lettre ça plante, il faut donc empêcher la première lecture de boucle sans condition. D'où le "while" en haut.

    En fait je faisais des tests pour générer motMasque, en rentrant la bonne lettre, de façon, à chaque boucle, à remplacer "*" par la lettre lettreEntree à son index indexLettreTrouvée. Donc je m'en serais apperçut dans la phase finale de tests.

    pour en revenir aux pointeurs, motMasque en est un pour que à chaque appel de la fonction afficherMotMasque sa chaîne de caractère soit modifiée et conservée dans la mémoire RAM. de sorte que les caractère qui ne sont pas "*" soient conservés à chaque essais du joueur.

    essai 1 : ****O*
    essai2 : M***O*
    etc...

  11. #11
    Membre éclairé Avatar de guitz
    Homme Profil pro
    Webdesigner
    Inscrit en
    Juillet 2006
    Messages
    717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Webdesigner

    Informations forums :
    Inscription : Juillet 2006
    Messages : 717
    Points : 741
    Points
    741
    Par défaut
    Bon mon pendu est à 99% développé, il reste une abbération que je m'en vais vous narrer :

    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include <time.h>
    #include <string.h>
    #include <ctype.h>
     
    char lireCaractere();
    void majMotMasque(char lettreEntree, char motSecret[], char motMasque[]);
     
    int main(int argc, char *argv[]){
     
        printf("Bienvenu dans le pendu !\n\n\n");
     
        char motSecret[] = "MARRON", motMasque[] = "******", lettreEntree = '_';
        int essaisRestants = 8;
     
     
        while(strcmp(motMasque, motSecret) != 0 && essaisRestants > 0){
     
            printf("\n\nVous avez %d essais", essaisRestants);
            //printf("\n\n%d", strcmp(motMasque, motSecret));
            //printf("\n\n%d %d", strlen(motMasque), strlen(motSecret));
            majMotMasque(lettreEntree, motSecret, motMasque);
            printf("\nQuel est le mot secret ? %s\nProposer une lettre : ", motMasque);
            lettreEntree = lireCaractere();
            essaisRestants--;
        }
     
        if(strcmp(motMasque, motSecret) == 0){
            printf("\n\nBravo !!!!");
        }else{
            printf("\n\nRecommence pauvre tache");
        }
     
        return 0;
    }
     
    //fonctions...
     
    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 (pour les effacer)
        while (getchar() != '\n') ;
        return caractere; // On retourne le premier caractère qu'on a lu
     
    }
     
    void majMotMasque(char lettreEntree, char motSecret[], char motMasque[]){
     
        char *substrMotSecret = NULL;
        int indexLettreTrouvee, i;
     
        substrMotSecret = strchr(motSecret, lettreEntree);
     
        while(substrMotSecret != NULL){
            indexLettreTrouvee = substrMotSecret-motSecret;
            substrMotSecret[0] = '_'; //on supprime la lettre choisie par le joueur pour que la boucle suivante ne le comptabilise pas.
            substrMotSecret = strchr(substrMotSecret, lettreEntree);
            motMasque[indexLettreTrouvee] = lettreEntree;
        }
     
        return motMasque;
    }
    strcmp(motMasque, motSecret) vaut toujours -1 même si motMasque vaut exactement motSecret (même longueur de chaîne, même caractères), de sorte que la boucle suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    while(strcmp(motMasque, motSecret) != 0 && essaisRestants > 0){
     
            ...
     
        }
    ne s'arrête que lorsque essaisRestants vaut 0. Autrement dit si l'utilisateur trouve la solution à l'essai 5, le jeu ne se termine pas.

    A votre avis à quoi est-ce dû ?

  12. #12
    Membre éclairé
    Avatar de Pouet_forever
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    671
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 671
    Points : 842
    Points
    842
    Par défaut
    Dans ta fonction majMotMasque tu modifies la valeur de motSecret, donc quand motMasque vaut MARRON, motSecret vaut ______
    Plus tu pédales moins fort, moins t'avances plus vite.

  13. #13
    Membre éclairé Avatar de guitz
    Homme Profil pro
    Webdesigner
    Inscrit en
    Juillet 2006
    Messages
    717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Webdesigner

    Informations forums :
    Inscription : Juillet 2006
    Messages : 717
    Points : 741
    Points
    741
    Par défaut
    parce que substrMotSecret n'est rien d'autre qu'un pointeur sur motSecret ? Et ce n'est en rien une chaîne de caractère ?

    Edit :

    Bon ba je te remercie c'est résolu, j'ai fait une copie de motSecret

    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
    void majMotMasque(char lettreEntree, char motSecret[], char motMasque[]){
     
        char *substrMotSecret = NULL, tempMotSecret[100] = {0};
        int indexLettreTrouvee, i;
     
        strcpy(tempMotSecret, motSecret);
        substrMotSecret = strchr(tempMotSecret, lettreEntree);
     
        while(substrMotSecret != NULL){
            indexLettreTrouvee = substrMotSecret-tempMotSecret;
            substrMotSecret[0] = '_'; //on supprime la lettre choisie par le joueur pour que la boucle suivante ne le comptabilise pas.
            substrMotSecret = strchr(substrMotSecret, lettreEntree);
            motMasque[indexLettreTrouvee] = lettreEntree;
        }
     
        return motMasque;
    }
    il me faudra assimiler le coup de la fonction native str qui renvoie le pointeur de la chaine principale mise en paramètre...

    Merci à tous de m'avoir fait gagner du temps

    PS : c'est mon tout premier programme en C, je suis tout fier, j'envisage d'ailleurs éventuellement de le commercialiser. Mais rassurez vous je ne manquerai pas de vous reverser qq dividendes

Discussions similaires

  1. Problème de char dans un pointeur de structure
    Par Odawin dans le forum Débuter
    Réponses: 4
    Dernier message: 29/04/2013, 17h02
  2. Ajouter un char* dans un char**
    Par lirycs78 dans le forum C
    Réponses: 3
    Dernier message: 25/12/2011, 10h18
  3. Réponses: 11
    Dernier message: 23/11/2011, 16h46
  4. Réponses: 1
    Dernier message: 22/12/2009, 11h40
  5. Réponses: 11
    Dernier message: 03/11/2006, 23h53

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