Erreur de segmentation en C

sabine -  
{psycho.} Messages postés 114 Statut Membre -
Bonjour,
voici le programme suivant qui choisit un mot parmi une liste, et qui met dans un tableau les caractères '_' tant que le mot contient une lettre:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void mettre(char *mot, char tab[]){
int i=0;
while((*mot+i-1) != '\0'){
tab[i]='_';
i++;
}
if((*mot+i-1)=='\0'){
tab[i]='\0';
}
}

int main(){
int i;
char words[3][15]={"baleine","tortue","meduse"};
char *mot;
srand(time(NULL));
mot=words[rand()%3];
char tableau[20];
mettre(mot, tableau);
return 0;
}

tant que mot n'est pas vide, on met _ dans tableau, mais j'ai une erreur de segmentation , pourtant la variable mot est bien initialisé dans le main, quelqu'un voit il d'où vient l'erreur svp?

merci
Configuration: Linux
Mozilla 1.9.0.16

8 réponses

  1. {psycho.} Messages postés 114 Statut Membre 8
     
    Salut,
    Pourquoi ce "-1" dans ton while :
    while((*mot+i-1) != '\0')
    

    En faisant ainsi, lorsque i est égal à 0, tu essayes d'accéder au dernier octet de mémoire avant la première lettre de ton mot. Donc si ton programme n'a pas les droits dessus, ça plante.
    0
    1. sabine
       
      oui psycho tu as raison et j'avais initialisé i=1 avnt meme ta réponse mais j'ai tjs une erreur de segmentation...
      0
  2. {psycho.} Messages postés 114 Statut Membre 8
     
    Arf, non, n'initialise pas à 1, laisse ton init à 0, mais enlève ton -1 du while, c'est beaucoup plus logique et c'est une bonne habitude à prendre étant donné qu'en C l'indexation des tableaux commence systématiquement à 0.

    Pour ton segfault, si ça ne vient pas de là, je regarderai ça dans la soirée, là je dois y aller!
    0
  3. {psycho.} Messages postés 114 Statut Membre 8
     
    Arf, CCM m'a fait sauter mon message, je la refais.

    Pour l'initialisation, tu devrais plutôt la laisser à 0 et enlever ton -1, c'est plus logique et c'est surtout une bonne habitude à prendre étant donné que l'indexation des tableaux en C commence systématiquement à 0 (comme dans la plupart (tous?) des autres langages.)

    Pour ton segfault, si ça ne vient pas de là, je me pencherai dessus dans la soirée, là je dois y aller donc pas le temps tout de suite.
    0
    1. sabine
       
      merci psycho c'est gentil, je vais essayer de trouver la solution en attendant mais sans grand espoir
      0
  4. alphon5o
     
    voici un corrigé de ton programme:

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    void mettre(char *mot, char tab[]){
      int i=0;
      while( *(mot + i ) != '\0'){ // et non *mot + i 
        tab[i]='_';
        i++;
      }
      if( *(mot+i )=='\0'){ // idem
        tab[i]='\0';
      }
    }
    
    
    int main(){
      //int i;
      char words[3][15]={"baleine","tortue","meduse"};
      char *mot;
      srand(time(NULL));
      mot=words[rand()%3];
      char tableau[20]; // pourkoi un tableau de 20 elements, vu kil doit autant de _ que de caractere dans mot
                               // il serait preferable que tu cree un tableau de taille = strlen(mot) ?
      mettre(mot, tableau);
      return 0;
    } 
    0
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. lami20j
     
    Salut,

    A vrai dire je n'ai pas trop compris ce que tu veux.

    lami20j@debian:~$ cat sabine.c
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include<string.h>
    
    int mettre(char *mot, char tab[]){
      int i=0;
      while((*mot++) != '\0')
        tab[i++]='_';
      tab[i]='\0';
      return i;
    }
    
    
    int main(){
      int taille,i;
      char *mot;
      char tableau[20];
      char words[3][15]={"baleine","tortue","meduse"};
      mot=malloc(15*sizeof(char));
    
      srand(time(NULL));
      strcpy(mot,words[rand()%3]);
      printf("%s\n",mot);
      taille=mettre(mot, tableau);
    
      printf("%d : ",taille);
      for(i=0;i<taille;++i)
        printf("%c ",tableau[0]);
      printf("\n");
      free (mot);
      return 0;
    }
    lami20j@debian:~$ gcc -Wall sabine.c
    lami20j@debian:~$ ./a.out
    baleine
    7 : _ _ _ _ _ _ _
    lami20j@debian:~$ ./a.out
    tortue
    6 : _ _ _ _ _ _
    lami20j@debian:~$ ./a.out
    tortue
    6 : _ _ _ _ _ _
    lami20j@debian:~$ ./a.out
    tortue
    6 : _ _ _ _ _ _
    lami20j@debian:~$ ./a.out
    meduse
    6 : _ _ _ _ _ _
    
    0
    1. sabine
       
      salut lamij, oui en fait je m'étais rendue compte de mon erreur en remplçant ma faute de frappe que tu signales bien par mot[i], donc j'ai bien ma fonction suivante:

      void mettre(char *mot, char tab[]){
      int i=0;
      while(*(mot+i) != '\0'){
      tableau[i]='_';
      i++;
      }
      tab[i]='\0';
      }

      cette fonction m'a l'air valide mais quand je la teste en main j'ai une boucle infinie curieusement:


      int main(){
      int i=0;
      char words[3][20]={"baleine","tortue","meduse"};
      char *mot;
      srand(time(NULL));
      mot=words[rand()%3];
      char tab[20];
      mettre(mot, tab);
      printf("Mot:");
      while(tab[i] != '\0'){
      printf("%c", tab[i]);
      }
      printf("\n");
      return 0;
      }

      normalement dès que tab[i]='\0' comme spécifié dans ma fonction mon while devrait s'arrêter qu'en dis tu? C'est juste mon programme que je dois un peu modifier pour qu'il ne boucle plus à l'infini, bien sur je n'ai pas le droit d'utiliser strlen malheureusement...
      0
  7. {psycho.} Messages postés 114 Statut Membre 8
     
    Bon, j'arrive un peu après la guerre finalement, mais là en tout cas, ta boucle infinie vient du while présent dans ta fonction main() : tu n'incrémentes pas i :)
    0
  8. lami20j
     
    Re,

    mon while devrait s'arrêter qu'en dis tu?

    Il ne s'arrêtera jamais si tu n'incrémente pas le i
    Dans ta boucle while i est toujours 0

    while(tab[i] != '\0'){
     printf("%c", tab[i++]);
    } 


    Et ici ce n'est pas tableau tableau[i]='_'; mais tab
    tab[i]='_'; 
    0
    1. sabine
       
      oui psycho tu as raison, merci bcp, et un grand merci à lamij aussi, tu m'as fait découvrir l'incrémentation dans le tableau lamij merci je connaissais pas, je continue mon travail :-).
      0
  9. {psycho.} Messages postés 114 Statut Membre 8
     
    Pas de souci, pense à mettre le sujet en résolu!
    Pour ce qui est des tableau, ceci dit, pour éviter de t'embêter à passer par le pointeur, tu peux directement faire comme ceci :
    char  tab[][] = {"baleine","tortue","meduse"};
    char *mot;
    int i,j;
    
    i = 0;
    while (tab[i] != 0) //au lieu de *(tab + i)
    {
      mot = tab[i];
      j = 0;
      while(mot[j] != 0)
        printf("%c", mot[j++]);
      printf("%c", '\n');
    }
    

    Et en encore plus compact...
    char  tab[][] = {"baleine","tortue","meduse"};
    char *mot;
    int i,j;
    
    i = -1;
    while (tab[++i])
    {
      j = -1
      while(mot[i][++j])
        write(1, tab[i][j], 1);
      write(1, 10, 1);  //10 = code ascii de '\n'
    }
    
    0