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 :

Problème de segmentation.


Sujet :

C

  1. #1
    Inactif
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 72
    Par défaut Problème de segmentation.
    Bonjour,

    dans le code suivant:

    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
     
    #include<stdio.h>
    #include<ctype.h>
    #include<stdlib.h>
    #include<float.h>
     
     
    int Analyse(char **ligne)
    {
      int res;
      char *mot;
      char *endptr;
     
      while(**ligne == ' ') (*ligne)++;
     
      /* on est en fin de chaine */
      if(**ligne == '\0')
        {
          fprintf(stderr,"erreur : rien n'a ete lu\n");
          return 1;
        }
     
      while(**ligne != '\0')
        {
          /* c'est un chiffre */
          if(isdigit(**ligne))
    	{
    	 res =  sscanf(*ligne,"%[0-9.]s ",mot);
    	 if(res != 1)
    	   return 1;
    	  strtod(mot,&endptr);
    	  if(*endptr != '\0')
    	    return 1;
     
    	  while(isdigit(**ligne) || **ligne == '.') (*ligne)++;
    	}
     
     
          /* c'est une lettre */
          if(isalpha(**ligne))
    	{
    	  res = sscanf(*ligne,"%[a-z]s ",mot);
    	  if(res != 1)
    	    return 1;
    	  while(isalpha(**ligne)) (*ligne)++;
    	}
        }
     
      if(**ligne == '\0')
        return 0;
      return 1;
    }
     
     
     
    int main(int argc, char*argv[])
    {
      int i;
      for(i=1;i<argc;i++)
        {
          if(Analyse(argv[i]))
    	{
    	  fprintf(stderr,"erreur\n");
    	  return 1;
    	}
          printf ("'%s'\n",argv[i]);
        }
      return 0;
    }
    j'obtient un seg fault.
    Quand j'utilises gdb,j'ai ce message:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Program exited normally.
    Est ce que vous voyez l'erreur?

    Merci

  2. #2
    Expert confirmé
    Avatar de PRomu@ld
    Homme Profil pro
    Ingénieur de Recherche
    Inscrit en
    Avril 2005
    Messages
    4 155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Ingénieur de Recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 4 155
    Par défaut
    Est ce que vous voyez l'erreur?
    Non j'ai pas mes lunettes.

    En fait rassure moi d'un truc : sous gdb, t'a bien lancé ton programme avec des paramètres ? Parce que si c'est pas le cas, c'est normal qu'il ne te trouve pas d'erreur. (en fait il ne rentre pas dans la boucle for de ton main)

    Exécute le avec des paramètres et là tu auras un beau segfault.

    [EDIT]
    Après un yeutage très furtif, il y a un truc qui me parait bizarre :
    ta fonction analyse prend un pointeur sur une chaine de caractère (char **) et tu lui passe une chaine de caractère (argv[i] est un char *)

  3. #3
    Membre confirmé
    Profil pro
    Étudiant
    Inscrit en
    Décembre 2005
    Messages
    163
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2005
    Messages : 163
    Par défaut
    Après un yeutage très furtif, il y a un truc qui me parait bizarre :
    ta fonction analyse prend un pointeur sur une chaine de caractère (char **) et tu lui passe une chaine de caractère (argv[i] est un char *)
    Ben c'est normal ça , non ? vu que le nom d'un tableau est un pointeur vers son premier élément ? plus l'* qui a avant dans son int main ça en fait bien un pointeur vers une chaine ?

  4. #4
    Expert confirmé
    Avatar de PRomu@ld
    Homme Profil pro
    Ingénieur de Recherche
    Inscrit en
    Avril 2005
    Messages
    4 155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Ingénieur de Recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 4 155
    Par défaut
    argv est un char ** et argv[i] est un char * et la fonction analyse attend un char ** en paramètre.

  5. #5
    Inactif
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 72
    Par défaut
    J'ai changé le char ** en char * dans la fonction Analyse mais j'ai toujours le seg fault

    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<ctype.h>
    #include<stdlib.h>
    #include<float.h>
     
     
    int Analyse(char *ligne)
    {
      int res;
      char *mot;
      char *endptr;
     
      while(*ligne == ' ') ligne++;
     
      /* on est en fin de chaine */
      if(*ligne == '\0')
        {
          fprintf(stderr,"erreur : rien n'a ete lu\n");
          return 1;
        }
     
      while(*ligne != '\0')
        {
          /* c'est un chiffre */
          if(isdigit(*ligne))
    	{
    	  res =  sscanf(ligne,"%[0-9.]s ",mot);
    	  if(res != 1)
    	   return 1;
    	  strtod(mot,&endptr);
    	  if(*endptr != '\0')
    	    return 1;
     
    	  while(isdigit(*ligne) || *ligne == '.') ligne++;
    	}
     
     
          /* c'est une lettre */
          if(isalpha(*ligne))
    	{
    	  res = sscanf(ligne,"%[a-z]s ",mot);
    	  if(res != 1)
    	    return 1;
    	  while(isalpha(*ligne)) ligne++;
    	}
        }
     
      if(*ligne == '\0')
        return 0;
      return 1;
    }
     
     
     
    int main(int argc, char*argv[])
    {
      int i;
      for(i=1;i<argc;i++)
        {
          if(Analyse(argv[i]))
    	{
    	  fprintf(stderr,"erreur\n");
    	  return 1;
    	}
          printf ("'%s'\n",argv[i]);
        }
      return 0;
    }

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    237
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 237
    Par défaut
    Salut!

    Juste deux choses :

    Si tu ne sais pas utiliser gdb, utilise printf!

    exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    printf ("ca passe\n"); fflush (stdout);
    res =  sscanf(ligne,"%[0-9.]s ",mot); 
    printf ("coucou?\n"); fflush (stdout);
    Ensuite, tu regarde ce qui s'est affiche ou non.
    Comme cela, tu remonte a ton erreur.

    Le fflush te permet de vider le buffer : il est imperatif de l'utiliser dans ces cas la.

    Une erreur vient du fait que tu utilise des char *
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
      char *mot;
      char *endptr;
    sans les avoir alloue dynamiquement...
    Du coup, ton programme a un comportement indefini...

  7. #7
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Par défaut
    Il faut faire par exemple char mot[128], c'est indispensable car sinon tu écros dans la nature avec ton sscanf (qui d'ailleurs ne sert strictement à rien, tu peux t'en passer en cherchant un peu). pour le pointeur char *end, ce n'est pas grave puisque tu passes l'adresse de end dans le strtod.
    "La haine seule fait des choix" - Koan Zen
    "Il ne faut pas être meilleur que les autres, il faut être meilleur que soi." Albert Jacquard
    "Ceux qui savent où ils ont posé leur parapluie ne sont pas alcooliques." - pgibonne.
    Faites du Prolog, ça vous changera les idées !
    Ma page Prolog
    Mes codes sources commentés

    Mon avatar : La Madeleine à la veilleuse de Georges de La Tour

  8. #8
    Expert confirmé
    Avatar de PRomu@ld
    Homme Profil pro
    Ingénieur de Recherche
    Inscrit en
    Avril 2005
    Messages
    4 155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Ingénieur de Recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 4 155
    Par défaut
    J'ai entendu dire que flush demandait le vidage du buffer mais que le système d'exploitation ne réalisait pas toujours ce vidage (quel égoïste celui là !!!)

    Par conséquent, j'ai pris l'habitude d'utiliser fprintf sur l'erreur standard. Et comme ceci je suis sur que le message s'affichera bien :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    fprintf(stderr," ... ");

  9. #9
    Inactif
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 72
    Par défaut
    Citation Envoyé par vince3320
    Salut!

    Juste deux choses :

    Si tu ne sais pas utiliser gdb, utilise printf!

    exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    printf ("ca passe\n"); fflush (stdout);
    res =  sscanf(ligne,"%[0-9.]s ",mot); 
    printf ("coucou?\n"); fflush (stdout);
    Ensuite, tu regarde ce qui s'est affiche ou non.
    Comme cela, tu remonte a ton erreur.

    Le fflush te permet de vider le buffer : il est imperatif de l'utiliser dans ces cas la.

    Une erreur vient du fait que tu utilise des char *
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
      char *mot;
      char *endptr;
    sans les avoir alloue dynamiquement...
    Du coup, ton programme a un comportement indefini...
    Bonjour,
    Merci de tes conseils,j'ai effectivement des resultats correctes.

    Je voudrais savoir :
    Outre le fait d'allouer ,comment il fallait que je m'y prenne pour argv dans la boucle si je garde char ** ligne dans ma fonction Analyse?

  10. #10
    Inactif
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 72
    Par défaut
    Citation Envoyé par Trap D
    Il faut faire par exemple char mot[128], c'est indispensable car sinon tu écros dans la nature avec ton sscanf (qui d'ailleurs ne sert strictement à rien, tu peux t'en passer en cherchant un peu). pour le pointeur char *end, ce n'est pas grave puisque tu passes l'adresse de end dans le strtod.
    J'ai utilisé sscanf car il me permet d'etre sur d'avoir un double ou une chaine de caractère bien écrit .
    Edit:en fait je ne comprends pas pourquoi, le programme reconnait
    "1222gfgfgg" et "dffdfdfd4447"

  11. #11
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Par défaut
    Comment reconnais-tu qu'une chaîne de caractères est bien écrite ?
    D'accord pour les entiers et les floats/double à la rigueur, bien que strtod et strtol soient plus précis car ils donnent l'endroit où la conversion s'arrête dans la chaîne passée en paramètre.
    "La haine seule fait des choix" - Koan Zen
    "Il ne faut pas être meilleur que les autres, il faut être meilleur que soi." Albert Jacquard
    "Ceux qui savent où ils ont posé leur parapluie ne sont pas alcooliques." - pgibonne.
    Faites du Prolog, ça vous changera les idées !
    Ma page Prolog
    Mes codes sources commentés

    Mon avatar : La Madeleine à la veilleuse de Georges de La Tour

  12. #12
    Inactif
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 72
    Par défaut
    Citation Envoyé par Trap D
    Comment reconnais-tu qu'une chaîne de caractères est bien écrite ?
    D'accord pour les entiers et les floats/double à la rigueur, bien que strtod et strtol soient plus précis car ils donnent l'endroit où la conversion s'arrête dans la chaîne passée en paramètre.
    En testant ,avec des parametres "non valides" pour mon exo ,le programme reconnait "gfgfg1112" et "1222hfdghfg" alors qu'il ne devrait pas.
    Existe t-il une manière de procéder pour etre sur du résultat?

  13. #13
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Par défaut
    Le principe est que tu définisses exactement ce que tu entends par nombre, nombre flottant, chaine de caractères, séparateurs (caractères à sauter).
    Tu peux ensuite faire un automate qui étudie la chaîne.
    Il te faut une variable indiquant le type de données que tu es en train de lire,
    une autre indiquant le début de la donnée que tu lis.
    Si tu n'y arrives pas, je te montrerai comment faire.
    "La haine seule fait des choix" - Koan Zen
    "Il ne faut pas être meilleur que les autres, il faut être meilleur que soi." Albert Jacquard
    "Ceux qui savent où ils ont posé leur parapluie ne sont pas alcooliques." - pgibonne.
    Faites du Prolog, ça vous changera les idées !
    Ma page Prolog
    Mes codes sources commentés

    Mon avatar : La Madeleine à la veilleuse de Georges de La Tour

Discussions similaires

  1. problème de segmentation
    Par Bargaroth dans le forum Réseau
    Réponses: 4
    Dernier message: 12/01/2008, 14h51
  2. Réponses: 6
    Dernier message: 01/11/2007, 18h44
  3. Problème java segmentation
    Par irdaa dans le forum Mandriva / Mageia
    Réponses: 1
    Dernier message: 28/03/2007, 08h24
  4. [Socket SSL] problème de "Segmentation fault"
    Par jesus144 dans le forum Programmation et administration système
    Réponses: 1
    Dernier message: 09/03/2007, 19h50
  5. Problème de segmentation ?
    Par julson dans le forum Assembleur
    Réponses: 2
    Dernier message: 23/12/2004, 18h33

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