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 :

Problème de pointeur


Sujet :

C

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    octobre 2018
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 21
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : octobre 2018
    Messages : 33
    Points : 21
    Points
    21
    Par défaut Problème de pointeur
    Bonjour !

    Je me tourne vers vous car j'ai un petit soucis de pointeur, et je ne comprends pas à vrai dire le problème.
    Le but de mon programme est de remplacer chaque lettre d'une chaine de caractère par sa place dans l'alphabet.

    J'ai donc rédigé ceci :

    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
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    char *alphabet_position(char *s) {
      for (size_t i = 0; i < strlen(s); i++) {
        switch(*s){
          case 'a':
            *s = 1 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'b':
            *s = 2 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'c':
            *s = 3 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'd':
            *s = 4 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'e':
            *s = 5 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'f':
            *s = 6 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'g':
            *s = 7 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'h':
            *s = 8 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'i':
            *s = 9 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'j':
            *s = 10 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'k':
            *s = 11 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'l':
            *s = 12 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'm':
            *s = 13 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'n':
            *s = 14 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'o':
            *s = 15 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'p':
            *s = 16 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'q':
            *s = 17 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'r':
            *s = 18 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 's':
            *s = 19 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 't':
            *s = 20 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'u':
            *s = 21 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'v':
            *s = 22 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'w':
            *s = 23 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'x':
            *s = 24 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'y':
            *s = 25 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'z':
            *s = 26 + '0';
            printf("Value of p : %c\n", *s);
            break;
        }
        s = s + 1;
      }
      return s;
    }
    Le problème, c'est que je tombe dès le début sur une erreur de segmentation (core dumped). Logiquement, si j'ai bien compris, c'est que je dois lire ou écrire sur quelque chose dont je ne devrais pas avoir le droit. Pourtant, je ne fais que lire la valeur de l'espace mémoire où pointe mon pointeur s, puis je change ça valeur. Quelque chose m'échappe alors ! Et j'aimerai bien savoir quoi !

    Je vous remercie en tout cas d'avance !

  2. #2
    Expert éminent
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    juillet 2013
    Messages
    3 017
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : juillet 2013
    Messages : 3 017
    Points : 6 700
    Points
    6 700
    Par défaut
    Quel code de m*rd* Putain j'ai perdu 3/ 10ième


    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
    char* alphabet_position(char* s) {
        char* res;
     
        if (s != NULL) { 
            char c;
     
            res = s;
     
            c = (*s);
     
            while (c != '\0') {
                if ((c >= 'a') && (c <= 'z')) {
                    c = (c - 'a' + 1);
                    (*s) = c;
                }
     
                ++s;
                c = (*s);
            }
        } else {
            res = NULL;
        }
     
        return res;
    }

    Édit 1 : La remarque de @edgarjacobs est pertinente. Je pensais à une erreur d'entrée mais plus à une chaîne sans le caractère final '\0'. Et c'est pour cela qu'on retourne un pointeur. On va travailler sur une chaîne temporaire (avec une allocation donc) et la retourner.
    Édit 2 : @Sve@r qui a remarqué que c'est + 1 dans l'expression (c - 'a' + 1) et non pas + le caractère '1'

  3. #3
    Membre éprouvé Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    mai 2011
    Messages
    407
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : mai 2011
    Messages : 407
    Points : 947
    Points
    947
    Par défaut
    Hello,

    Comment appelles-tu ta fonction ? Car si tu l'appelles comme ceci alphabet_position("abc"); , la chaine de caractères "abc" est stockée dans une zone mémoire non modifiable (read-only), et tenter d'y écrire qqchose provoque un segfault.

  4. #4
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    février 2006
    Messages
    7 486
    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 : 7 486
    Points : 21 313
    Points
    21 313
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par LePtitBen Voir le message
    J'ai donc rédigé ceci :

    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
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    char *alphabet_position(char *s) {
      for (size_t i = 0; i < strlen(s); i++) {
        switch(*s){
          case 'a':
            *s = 1 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'b':
            *s = 2 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'c':
            *s = 3 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'd':
            *s = 4 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'e':
            *s = 5 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'f':
            *s = 6 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'g':
            *s = 7 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'h':
            *s = 8 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'i':
            *s = 9 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'j':
            *s = 10 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'k':
            *s = 11 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'l':
            *s = 12 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'm':
            *s = 13 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'n':
            *s = 14 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'o':
            *s = 15 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'p':
            *s = 16 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'q':
            *s = 17 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'r':
            *s = 18 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 's':
            *s = 19 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 't':
            *s = 20 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'u':
            *s = 21 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'v':
            *s = 22 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'w':
            *s = 23 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'x':
            *s = 24 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'y':
            *s = 25 + '0';
            printf("Value of p : %c\n", *s);
            break;
          case 'z':
            *s = 26 + '0';
            printf("Value of p : %c\n", *s);
            break;
        }
        s = s + 1;
      }
      return s;
    }
    Sans déconner t''es fier de ce code ? Tu t'es tapé en switch tous les caractères de 'a' à 'z' et tu ne t'es pas dit qu'il y avait peut-être moyen de factoriser ? Et t'as même recopié à l'identique le printf() 26 fois. Ca pour un code "con"...
    Voyons: pour 'a' tu ajoutes 1. Pour 'b' tu ajoutes 2 (un rang après 'a'). Pour 'c' tu ajoutes 3 (deux rangs après 'a'). Bref ça devient trivial => suffit d'ajouter à chaque fois *s - 'a' + 1. Désolé mais plus un code est moins long moins il y a plus de bugs.

    Autres remarques: on ne boucle jamais sur strlen() car cette fonction se coltine toute la chaine pour te renvoyer sa longueur => bref pour une chaine de n caractères ça te fait n² itérations.
    En plus "s" monte dans la boucle donc fatalement strlen(s) descend (si "s" vaut "abcde" alors au tour d'après elle vaut "bcde") tandis que "i" monte. Donc à chaque itération t'as la borne gauche qui monte et la borne droite qui descend. Tu penses que ta boucle balayera toute la chaine ???

    Donc soit tu stockes la longueur dans une variable et tu boucles dessus, soit tu cherches le '\0'.

    Dernier détail: si on te demande de remplacer 'a' par sa position dans l'alphabet, alors 'a' devient 1, pas 1 + '0'. Mais bon, ça c'est moins important (le résultat est bon à une translation près).

    Et sinon la remarque d'edgarjacobs est primordiale. Si tu appelles ta fonction avec une chaine statique, alors cette chaine est invariante et en tentant de la modifier ça ne peut que planter.
    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

  5. #5
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    octobre 2018
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 21
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : octobre 2018
    Messages : 33
    Points : 21
    Points
    21
    Par défaut
    Merci tout d'abord de vos réponses !

    On commence tous quelque part ! Et il est vrai que j'ai réfléchi plutôt naïvement.
    Mais mon problème vient surtout de ce qu'évoque edgar. Je l'appelle ainsi alphabet_position("abc");.
    Néanmoins, pour strlen(), je pensais que dans la boucle for, elle n'était appelée qu'une fois, et non à chaque itération.
    Merci en tout cas de ces précieux conseils !

  6. #6
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    février 2006
    Messages
    7 486
    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 : 7 486
    Points : 21 313
    Points
    21 313
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par LePtitBen Voir le message
    On commence tous quelque part ! Et il est vrai que j'ai réfléchi plutôt naïvement.
    Je ne t'ai pas reproché de débuter (ça je ne le fais jamais) mais justement de ne pas avoir réfléchi du tout pendant que tu tapais tes lignes...

    Citation Envoyé par LePtitBen Voir le message
    Néanmoins, pour strlen(), je pensais que dans la boucle for, elle n'était appelée qu'une fois, et non à chaque itération.
    for (A; B; C) => "A" n'est fait qu'une fois avant le bloc, "B" est évalué à chaque itération (évidemment puisqu'il faut détecter si la condition est toujours valide) et "C" est fait aussi à chaque itération mais en fin de bloc. C'est sûrement écris dans ton cours.
    Si encore "s" ne change pas peut-être que l'optimiseur de compilation détectera l'invariance de strlen(s) et optimisera le truc (Bktero est super calé là dessus et s'il passe ici il pourra t'en dire plus) mais perso je préfère ne compter que sur moi-même (surtout que pour balayer une chaine, c'est pas compliqué de chercher le '\0') => while (*s != '\0').

    Mais quoi qu'il en soit, ici "s" varie donc aucune optimisation possible par le compilateur. Tu te coltineras le strlen() à chaque tour.
    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

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème de pointeurs..embrouillé
    Par Frenchy dans le forum C++
    Réponses: 11
    Dernier message: 10/03/2005, 16h33
  2. Problème de pointeur avec un TQuery
    Par Oluha dans le forum Bases de données
    Réponses: 3
    Dernier message: 25/01/2005, 13h57
  3. Problème de pointeur
    Par toma_lille dans le forum C++
    Réponses: 1
    Dernier message: 07/12/2004, 21h26
  4. [MFC] Problème de pointeur !!
    Par acastor dans le forum MFC
    Réponses: 7
    Dernier message: 19/03/2004, 15h50
  5. TBitmap et problèmes de pointeurs...
    Par benj63 dans le forum C++Builder
    Réponses: 8
    Dernier message: 28/07/2003, 13h39

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