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 :

Programme qui n'affiche pas ce que je souhaite


Sujet :

C

  1. #1
    Membre habitué
    Inscrit en
    Septembre 2005
    Messages
    747
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 747
    Points : 174
    Points
    174
    Par défaut Programme qui n'affiche pas ce que je souhaite
    Bonjour,
    j'aurais besoin d'aide car ce programme ne fait pas ce que je souhaite qu'il fasse,à savoir lire une chaine de caractère pour ensuite construire un arbre binaire.
    Une fois que l'arbre est construit,je souhaite l'afficher en infixe.
    Merci à ceux qui m'aideront.

    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
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <ctype.h>
     
     
    enum Type {Operateur, Constante, Variable};
     
     
    union Info  
    {
    	double cte;
    	char *nom;
    	char op;
    };
     
    struct noeud{
    	enum Type type;
    	union Info info;
    	struct noeud *gauche;
    	struct noeud *droit;
    };
     
    typedef struct noeud Noeud;
    typedef struct noeud * Expression;
     
     
     
    Expression AnalyseExpression(char **ligne)
    {
     
      Expression e;
      char c;
     
      while(**ligne == ' ') (*ligne ++);
     
      /* on est en fin de chaine */
      if(**ligne == '\0')
        {
          fprintf(stderr,"erreur : il doit manquer des operandes\n");
          return NULL;
        }
     
      e = (Expression)malloc(sizeof(Noeud));
      if(e == NULL) return e;
     
      /* c'est un chiffre */
      if(isdigit(**ligne))
        {
          e->type = Constante;
          sscanf(*ligne,"%lf ",&(e->info.cte));
          while(isdigit(**ligne) || **ligne == '.') (*ligne)++;
        }
     
      else 
        {
          /* c'est une lettre */
          if(isalpha(**ligne))
    	{
    	  e->type = Variable;
    	  sscanf(*ligne,"%s ",e->info.nom);
    	  while(isalpha(**ligne)) (*ligne)++;
    	}
          else
    	{
    	  /* le caractere est un operateur */
    	  c=*((*ligne)++);
    	  if(c == '+' || c == '-' || c == '*' || c == '/')
    	    {
    		  e->type = Operateur;
    		  e->info.op = c;
    		  e->gauche = AnalyseExpression(ligne);
    		  e->droit = AnalyseExpression(ligne);
    	    }
    	  else if(c == '@' || c == '~')
    	    {
    	      e->type = Operateur;
    	      e->info.op = c;
    	      e->gauche = AnalyseExpression(ligne);
    	      e->droit = NULL;
    	    }
    	  else printf("Erreur,'%c' n'est pas un operateur prevu\n",c);
    	}
        }
      return e;
    }
     
     
    /* Affichage de l'arbre en infixe */
    void Infixe(Expression e)
    {
      switch(e->type)
        {
        case Constante:
          printf("%f",e->info.cte);
          break;
     
        case Variable:
          printf("%s",e->info.nom);
          break;
     
        case Operateur:
          switch(e->info.op)
    	{
    	  case'+':
    	    case'-':/* affichage infixe sans () */
    	    Infixe(e->gauche);
    	  if(e->info.op == '+') printf("+"); 
    	  else printf("-");
    	  Infixe(e->droit);
    	  break;
    	  case'*':
    	    case'/':/* affichage infixe avec () */
    	    if(e->gauche->type != Operateur)
    	      Infixe(e->gauche);
    	    else
    	      {
    		printf("(");
    		Infixe(e->gauche);
    		printf(")");
    	      }
    	  if(e->info.op == '*') printf("*"); 
    	  else printf("/");
     
    	  if(e->droit->type != Operateur)
    	    Infixe(e->droit);
    	  else
    	    {
    	      printf("(");
    	      Infixe(e->droit);
    	      printf(")");
    	    }
    	  break;
    	  case'@':/* affichage prefixe */
    	    printf("@");
    	  Infixe(e->gauche);
    	  break;
    	  case'~':
    	    printf("~");
    	  Infixe(e->gauche);
    	  break;
    	}
        }
    }
     
     
    int main (void)
    {
      char *ligne = "+ 1 2";
      Expression e = NULL;
      e=AnalyseExpression(&ligne);
      Infixe(e);
      return 0;
     
    }

  2. #2
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    C'est sympa d'expliquer en même temps ce que ce programme ne fait pas... Où est-ce qu'il bloque, où est-ce qu'il y a un problème...

    Bref, bien que je ne ferais pas ton parcours avec ton pointeur comme ça (une bonne raison: tu perds entièrement ta chaîne de caractère de base, bonjour les fuites de mémoire...)

    Mais bon, ton erreur se trouve ici:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    (*ligne ++); -> (*ligne)++;
    Du moins chez moi... Ensuite j'ai même tenté avec:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    char *ligne = "* + 1 2 3";
    et il me rend:
    (1.000000+2.000000)*3.000000

  3. #3
    Membre habitué
    Inscrit en
    Septembre 2005
    Messages
    747
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 747
    Points : 174
    Points
    174
    Par défaut
    Mais bon, ton erreur se trouve ici:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    (*ligne ++); -> (*ligne)++;
    J'ai remplacé la ligne (*ligne)++ par (*ligne ++);

    Du moins chez moi... Ensuite j'ai même tenté avec:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    char *ligne = "* + 1 2 3";
    et il me rend:

    (1.000000+2.000000)*3.000000
    C'est bizarre que ça marche chez toi car en recompilant,j'ai ceci:
    erreur : il doit manquer des operandes
    erreur : il doit manquer des operandes
    Segmentation fault
    Ce que tu as obtenu,est ce que je souhaites avoir

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Au passage, c'est normal que "* + 1 2 3" donne (1+2)*3...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Je ne vois pas trop ce qui pourrait poser probleme en lisant ton code (d'accord, je le fais en diagonale mais bon...)

    Prend ceci comme AnalyseExpression et dit moi ce qu'il fait...

    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
     
    Expression AnalyseExpression(char **ligne)
    {
     
      Expression e;
      char c;
     
     printf("Start %p %p %c\n",ligne,*ligne,**ligne);
     
      while(**ligne == ' ') {printf("Here\n");(*ligne)++;}
     
     printf("Analyse terminée\n");
      /* on est en fin de chaine */
      if(**ligne == '\0')
        {
          fprintf(stderr,"erreur : il doit manquer des operandes\n");
          return NULL;
        }
     
      e = (Expression)malloc(sizeof(Noeud));
      if(e == NULL) return e;
     
      /* c'est un chiffre */
      if(isdigit(**ligne))
        {
        printf("Is digit\n");
          e->type = Constante;
          sscanf(*ligne,"%lf ",&(e->info.cte));
          while(isdigit(**ligne) || **ligne == '.') (*ligne)++;
              printf("Is digit over\n");
        }
     
      else
        {
            printf("Is alpha\n");
          /* c'est une lettre */
          if(isalpha(**ligne))
       {
         printf("Yes\n");
         e->type = Variable;
         sscanf(*ligne,"%s ",e->info.nom);
         while(isalpha(**ligne)) (*ligne)++;
       }
          else
       {
       printf("No\n");
         /* le caractere est un operateur */
         c=*((*ligne)++);
         if(c == '+' || c == '-' || c == '*' || c == '/')
           {
           printf("Operator: %c\n",c);
            e->type = Operateur;
            e->info.op = c;
    	printf("Calling %p %p\n",ligne,*ligne);
            e->gauche = AnalyseExpression(ligne);
            e->droit = AnalyseExpression(ligne);
    	printf("Calling\n");
           }
         else if(c == '@' || c == '~')
           {
             e->type = Operateur;
             e->info.op = c;
             e->gauche = AnalyseExpression(ligne);
             e->droit = NULL;
           }
         else printf("Erreur,'%c' n'est pas un operateur prevu\n",c);
       }
        }
      return e;
    }
    Moi ca affiche:
    Start 0xbfffe1f0 0x8048c74 +
    Analyse terminée
    Is alpha
    No
    Operator: +
    Calling 0xbfffe1f0 0x8048c75
    Start 0xbfffe1f0 0x8048c75
    Here
    Analyse terminée
    Is digit
    Is digit over
    Start 0xbfffe1f0 0x8048c77
    Here
    Analyse terminée
    Is digit
    Is digit over
    Calling
    Analyse terminée
    1.000000+2.00000
    Jc

  6. #6
    Membre habitué
    Inscrit en
    Septembre 2005
    Messages
    747
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 747
    Points : 174
    Points
    174
    Par défaut
    fearyourself,le compilateur m'affiche ceci:

    Start 0xbffff964 0x8048bc0 +
    Analyse terminée
    Is alpha
    No
    Operator: +
    Calling 0xbffff964 0x8048bc1
    Start 0xbffff964 0x8048bc1
    Here
    Analyse terminée
    Is digit
    Is digit over
    Start 0xbffff964 0x8048bc3
    Here
    Analyse terminée
    Is digit
    Is digit over
    Calling
    1.000000+2.000000

  7. #7
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    fearyourself,le compilateur m'affiche ceci:
    Déjà c'est le programme qui l'affiche...

    Ensuite, que fait-il après, il s'arrête simplement?

  8. #8
    Membre habitué
    Inscrit en
    Septembre 2005
    Messages
    747
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 747
    Points : 174
    Points
    174
    Par défaut
    Citation Envoyé par fearyourself
    Ensuite, que fait-il après, il s'arrête simplement?
    Oui,il s'arrete

  9. #9
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Donc il n'affiche plus ceci:

    erreur : il doit manquer des operandes
    erreur : il doit manquer des operandes
    Il ne fait plus d'erreur de segmentations?

    A la limite, tente avec un debuggueur pour voir où il s'arrête vraiment...

    Autre question:

    Mets un printf("Yo\n"); avant ta fonction infixe et comme première instruction de infixe... Qu'est-ce qu'il fait...

    Mais bon, c'est tout de même bizarre qu'il fonctionne sans problème chez moi...

  10. #10
    Membre habitué
    Inscrit en
    Septembre 2005
    Messages
    747
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 747
    Points : 174
    Points
    174
    Par défaut
    Citation Envoyé par fearyourself
    Donc il n'affiche plus ceci:

    erreur : il doit manquer des operandes
    erreur : il doit manquer des operandes
    Il ne fait plus d'erreur de segmentations?

    A la limite, tente avec un debuggueur pour voir où il s'arrête vraiment...

    Autre question:

    Mets un printf("Yo\n"); avant ta fonction infixe et comme première instruction de infixe... Qu'est-ce qu'il fait...

    Mais bon, c'est tout de même bizarre qu'il fonctionne sans problème chez moi...
    Merci pour ton aide,j'ai retesté et le programme fonctionne parfaitement,ol
    m'affiche ce que je souhaite lorque c'est des nombres ou null lorsque je tape n'importe quoi

    Si tu pouvais également m'aider pour cette fonction.
    J'ai crée une fonction Eval qui évalue,une expression (arbre) lorsque toutes les feuilles de l'arbre sont des réels (de type double).
    J'aimerais avoir une aide concernant la simplification de l'expression lorsque l'évaluation totale n'est pas possible.
    Je m'explique:
    si l'arbre est compose de + * 1 2 3 la fonction renvoie 5
    mais si c'est + * 1 2 x la fonction renvoye 2+x
    Merci


    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
      1. #include <stdio.h>
       2. #include <string.h>
       3. #include <stdlib.h>
       4. #include <ctype.h>
       5. #include <math.h>
       6.
       7.
       8. enum Type {Operateur, Constante, Variable};
       9.
      10.
      11. union Info 
      12. {
      13.   double cte;
      14.   char *nom;
      15.   char op;
      16. };
      17.
      18. struct noeud{
      19.   enum Type type;
      20.   union Info info;
      21.   struct noeud *gauche;
      22.   struct noeud *droit;
      23. };
      24.
      25. typedef struct noeud Noeud;
      26. typedef struct noeud * Expression;
      27.
      28.
      29.
      30.
      31.
      32. double Eval(Expression *e)
      33. {
      34.   double r1,r2;
      35.  
      36.   if((*e)->type == Constante) return((*e)->info.cte);
      37.  
      38.   if ((*e)->type == Operateur)
      39.     {
      40.       r1=Eval(&(*e)->gauche);
      41.       r2=Eval(&(*e)->droit);
      42.       switch ((*e)->info.op)
      43.       {
      44.       case '+':return(r1+r2);
      45.       case '-':return(r1-r2);
      46.       case '*':return(r1*r2);
      47.       case '/':return(r1/r2);
      48.       }
      49.     }
      50.   /* si aucun return n'a t effectu jusqu'ici*/
      51.   puts("erreur (code opratoire inconnu par exemple)");
      52.   return(0);
      53. }
      54.
      55.
      56. double Plus (double x, double y)
      57. {
      58.   return x+y;
      59. }
      60.
      61. double Moins(double x, double y)
      62. {
      63.   return x-y;
      64. }
      65.
      66. double Mul(double x, double y)
      67. {
      68.   return x*y;
      69. }
      70.
      71. double Div(double x, double y)
      72. {
      73.   return x/y;
      74. }
      75.
      76.
      77. double (*FonctionOperateur(char operateur))(double, double)
      78. {
      79.   char ops[]={'+','-','*','/','\0'};
      80.   double (*fcts[])(double,double)={Plus,Moins,Mul,Div,NULL};
      81.   unsigned i;
      82.   for(i=0;fcts[i]!=NULL&&ops[i]!=operateur;++i);
      83.   return fcts[i];
      84. }

  11. #11
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    La simplification est assez simple : tu parcours l'arbre de manière postfixe comme suit:

    Pour chaque noeud :
    * Si le noeud est une feuille, on ne fait rien
    * Si le noeud est un opérateur et que ses deux opérandes sont des constantes, on effectue le calcul et on transforme le noeud en constante.

    Ainsi, toutes les constantes auront été simplifiées.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  12. #12
    Membre habitué
    Inscrit en
    Septembre 2005
    Messages
    747
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 747
    Points : 174
    Points
    174
    Par défaut
    Citation Envoyé par Médinoc
    La simplification est assez simple : tu parcours l'arbre de manière postfixe comme suit:

    Pour chaque noeud :
    * Si le noeud est une feuille, on ne fait rien
    * Si le noeud est un opérateur et que ses deux opérandes sont des constantes, on effectue le calcul et on transforme le noeud en constante.

    Ainsi, toutes les constantes auront été simplifiées.
    Salut,
    j'ai écrit la fonction de simplification mais le programme m'affiche null à la place de la variable :
    (1.000000+2.000000)*(null)->3.000000*(null)


    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
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
     
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <ctype.h>
     
     
    enum Type {Operateur, Constante, Variable};
     
     
    union Info 
    {
      double cte;
      char *nom;
      char op;
    };
     
    struct noeud{
      enum Type type;
      union Info info;
      struct noeud *gauche;
      struct noeud *droit;
    };
     
    typedef struct noeud Noeud;
    typedef struct noeud * Expression; 
     
     
    Expression AnalyseExpression(char **ligne)
    {
     
      Expression e;
      char c;
     
      while(**ligne == ' ') (*ligne)++;
     
      /* on est en fin de chaine */
      if(**ligne == '\0')
        {
          fprintf(stderr,"erreur : il doit manquer des operandes\n");
          return NULL;
        }
     
      e = (Expression)malloc(sizeof(Noeud));
      if(e == NULL) return e;
     
      /* c'est un chiffre */
      if(isdigit(**ligne))
        {
          e->type = Constante;
          sscanf(*ligne,"%lf ",&(e->info.cte));
          while(isdigit(**ligne) || **ligne == '.') (*ligne)++;
        }
     
      else
        {
          /* c'est une lettre */
          if(isalpha(**ligne))
    	{
    	  e->type = Variable;
    	  sscanf(*ligne,"%s ",e->info.nom);
    	  while(isalpha(**ligne)) (*ligne)++;
    	}
          else
    	{
    	  /* le caractere est un operateur */
    	  c=*((*ligne)++);
    	  if(c == '+' || c == '-' || c == '*' || c == '/')
    	    {
    	      e->type = Operateur;
    	      e->info.op = c;
    	      e->gauche = AnalyseExpression(ligne);
    	      e->droit = AnalyseExpression(ligne);
    	    }
    	  else if(c == '@' || c == '~')
    	    {
    	      e->type = Operateur;
    	      e->info.op = c;
    	      e->gauche = AnalyseExpression(ligne);
    	      e->droit = NULL;
    	    }
    	  else printf("Erreur,'%c' n'est pas un operateur prevu\n",c);
    	}
        }
      return e;
    }
     
     
     
    /* Affichage de l'arbre en infixe */
    void Infixe(Expression e)
    {
      switch(e->type)
        {
        case Constante:
          printf("%f",e->info.cte);
          break;
     
        case Variable:
          printf("%s",e->info.nom);
          break;
     
        case Operateur:
          switch(e->info.op)
    	{
    	  case'+':
    	    case'-':/* affichage infixe sans () */
    	    Infixe(e->gauche);
    	  if(e->info.op == '+') printf("+");
    	  else printf("-");
    	  Infixe(e->droit);
    	  break;
    	  case'*':
    	    case'/':/* affichage infixe avec () */
    	    if(e->gauche->type != Operateur)
    	      Infixe(e->gauche);
    	    else
    	      {
    		printf("(");
    		Infixe(e->gauche);
    		printf(")");
    	      }
    	  if(e->info.op == '*') printf("*");
    	  else printf("/");
     
    	  if(e->droit->type != Operateur)
    	    Infixe(e->droit);
    	  else
    	    {
    	      printf("(");
    	      Infixe(e->droit);
    	      printf(")");
    	    }
    	  break;
    	  case'@':/* affichage prefixe */
    	    printf("@");
    	  Infixe(e->gauche);
    	  break;
    	  case'~':
    	    printf("~");
    	  Infixe(e->gauche);
    	  break;
    	}
        }
    } 
     
     
    double Eval(Expression *e)
    {
      double r1,r2;
     
      if((*e)->type == Constante) return((*e)->info.cte);
     
      if ((*e)->type == Operateur)
        {
          r1=Eval(&(*e)->gauche);
          r2=Eval(&(*e)->droit);
          switch ((*e)->info.op)
    	{
    	case '+':return(r1+r2);
    	case '-':return(r1-r2);
    	case '*':return(r1*r2);
    	case '/':return(r1/r2);
    	}
        }
      /* si aucun return n'a t effectu jusqu'ici*/
      puts("erreur (code opratoire inconnu par exemple)");
      return(0);
    } 
     
     
    void Simplification(Expression *e)
    {
      double res;
     
      if (*e == NULL) return;
     
      if((*e)->gauche == NULL && (*e)->droit == NULL) return;
     
      Simplification(&(*e)->gauche);
      Simplification(&(*e)->droit);
     
      if((*e)->gauche->type == Constante && (*e)->droit->type == Constante)
        {
          res = Eval(e);
          (*e)->info.cte = res;
          (*e)->type = Constante; 
        }
    }
     
     
     
    int main (void)
    {
      double res;
      char *ligne = "* + 1 2 x";
      Expression e = NULL;
      e=AnalyseExpression(&ligne);
      Infixe(e);
      printf("->");
      Simplification(&e);
      Infixe(e);
      printf("\n");
      return 0;
     
    }

  13. #13
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    eh bien, c'est bizarre, car je ne vois pas d'erreur dans ta fonction de simplification...
    Normalement, ça devrait marcher, en transformant tout opérateur qui fait une opération sur deux constantes en une autre constante...

    Edit:
    J'ai trouvé une erreur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if((*e)->gauche == NULL && (*e)->droit == NULL) return;
    Là, que se passe -t-il si l'un des deux est NULL et pas l'autre ? Normalement, ça ne devrait pas ce produire, donc ça ne devrait pas non plus être accepté : remplace ton && par un ||...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  14. #14
    Membre habitué
    Inscrit en
    Septembre 2005
    Messages
    747
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 747
    Points : 174
    Points
    174
    Par défaut
    Citation Envoyé par Médinoc
    eh bien, c'est bizarre, car je ne vois pas d'erreur dans ta fonction de simplification...
    Normalement, ça devrait marcher, en transformant tout opérateur qui fait une opération sur deux constantes en une autre constante...

    Edit:
    J'ai trouvé une erreur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if((*e)->gauche == NULL && (*e)->droit == NULL) return;
    Là, que se passe -t-il si l'un des deux est NULL et pas l'autre ? Normalement, ça ne devrait pas ce produire, donc ça ne devrait pas non plus être accepté : remplace ton && par un ||...
    En faisant le changement,il se produit toujours le problème.
    Il me semble que l'erreur vient de la fonction AnalyseExpression (le cas de la variable) mais je ne vois pas ou est le problème.
    Aurais tu une idée?

  15. #15
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Voici ton erreur, ta structure est définie comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    union Info
    {
      double cte;
      char *nom;
      char op;
    };
    Mais lorsque tu affectes quelque chose à ton nom, tu fais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    sscanf(*ligne,"%s ",e->info.nom);
    Or, tu n'as pas alloué la mémoire correctement, une solution serait de faire 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
     
    Expression AnalyseExpression(char **ligne)
    {
     
      Expression e;
      char c;
      char *place;
      int cnt;
     
      .........
     
         //Calcule de la taille du nom de la variable
         cnt = 0;
         place = *ligne;
         //De toute facon, c'est ce que va faire sscanf -> chercher le prochain espace ou la fin de la chaine...
         while( (*place != '\0') && (*place != ' ') )
         	{
            //compter le nombre de caractere de cette variable
    	cnt++;
    	place++;
    	}
         e->info.nom = (char *) malloc(cnt*sizeof(char));
         sscanf(*ligne,"%s ",e->info.nom);
    ......
    }

  16. #16
    Membre habitué
    Inscrit en
    Septembre 2005
    Messages
    747
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 747
    Points : 174
    Points
    174
    Par défaut
    Citation Envoyé par fearyourself
    Voici ton erreur, ta structure est définie comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    union Info
    {
      double cte;
      char *nom;
      char op;
    };
    Mais lorsque tu affectes quelque chose à ton nom, tu fais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    sscanf(*ligne,"%s ",e->info.nom);
    Or, tu n'as pas alloué la mémoire correctement, une solution serait de faire 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
     
    Expression AnalyseExpression(char **ligne)
    {
     
      Expression e;
      char c;
      char *place;
      int cnt;
     
      .........
     
         //Calcule de la taille du nom de la variable
         cnt = 0;
         place = *ligne;
         //De toute facon, c'est ce que va faire sscanf -> chercher le prochain espace ou la fin de la chaine...
         while( (*place != '\0') && (*place != ' ') )
         	{
            //compter le nombre de caractere de cette variable
    	cnt++;
    	place++;
    	}
         e->info.nom = (char *) malloc(cnt*sizeof(char));
         sscanf(*ligne,"%s ",e->info.nom);
    ......
    }
    Merci,de ta réponse

  17. #17
    Membre habitué
    Inscrit en
    Septembre 2005
    Messages
    747
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 747
    Points : 174
    Points
    174
    Par défaut
    Bonjour,

    j'ai un problème avec mon code.
    Mon code a pour but de lire une chaine de caractère (variable ou fonction) et de réafficher ce qui est écrit mais en enlevant les espaces .
    Dans l'exemple mis dans le main,le programme ne m'affiche que fonct.
    Est ce que quelqu'un a une idée du pourquoi de cette affichage?

    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
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include <float.h>
     
    #define VARIABLE 0
    #define FONCTION 1
     
     
    void espace(char **ligne)
    {
      while(**ligne == ' ') (*ligne++);
    }
     
     
    /* Fonction qui gre les espaces pour les parametres des fonctions */
    void espace2(char **ligne)
    {
      while(**ligne == ' ' || **ligne == ',' ) (*ligne++);
    }
     
     
    int analyse(char **ligne)
    {
      char *nom;
      char *parametres;
      int nb_parametres;
      int type;
      int cpt1,cpt2;
      char *mot1,*mot2;
      int i;
     
      espace(ligne);
     
      /* on est en fin de chaine */
      if(**ligne == '\0')
        {
          fprintf(stderr,"erreur\n");
          return 1;
        }
     
      /* on n'est pas en presence d'un mot */  
      if(!(isalpha(**ligne))) return 1;
     
     
      /* c'est une lettre */
      if(isalpha(**ligne))
        {
          /* Calcule de la taille du nom de la variable */
          cpt1 = 0;
          mot1 = *ligne; 
     
     
          while( (*mot1 != '\0') && (*mot1 != ' ') )
    	{
    	  /* compter le nombre de caractere de cette variable */
    	  cpt1++;
    	  mot1++;
    	}
          nom = (char *) malloc(cpt1*sizeof(char)); 
          sscanf(*ligne,"%s",nom);
          printf("%s",nom);
        }
     
      espace(ligne);
     
     
      /* c'est une fonction */
      if(**ligne == '(')
        {
          espace(ligne++);
          /* Calcule de la taille du tableau de parametres */
          cpt2 = 0;
          mot2 = *ligne; 
     
         while(*mot2 != ')' )
           {
    	 /* compter le nombre de caractere de cette variable */
    	 cpt2++;
    	 mot2++;
    	 espace2(&mot2);
           }
         *ligne = mot2;
         if(**ligne != ')') return 1;
         type = FONCTION;
         nb_parametres = cpt2;
         parametres = (char *) malloc(cpt2*sizeof(char)); 
         sscanf(*ligne,"%s",parametres);
         for(i=0;i<nb_parametres;i++)
           printf("%s(%c,)",nom,parametres[i]);
        }
     
      /* c'est une variable */
      else type = VARIABLE;
     
      return 0;
    }
     
     
    int main(void)
    {
      char *ligne = "fonct (x,  y ,z)";
     
      if(analyse(&ligne))
        {
          fprintf(stderr,"erreur\n");
          return 1;
        }
      printf("\n");
      return 0;
    }

  18. #18
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Je te conseillerais de prendre une demi-journée pour enlever tous les pointeurs inutiles... C'est difficile à gérer surtout lorsque tu n'as pas vraiment besoin d'une double indirection...

    Il y a beaucoup de raisons pour expliquer que ça ne marche pas:

    J'ai déjà corrigé ceci chez toi:
    n'est pas pareil que
    Aussi:
    n'est pas pareil que:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    (*ligne)++; 
    espace(ligne);
    Enfin,

    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
     
         while(*mot2 != ')' )
           {
        /* compter le nombre de caractere de cette variable */
        cpt2++;
        mot2++;
        espace2(&mot2);
           }
         *ligne = mot2;
         if(**ligne != ')') return 1;
         type = FONCTION;
         nb_parametres = cpt2;
         parametres = (char *) malloc(cpt2*sizeof(char));
         sscanf(*ligne,"%s",parametres);
         for(i=0;i<nb_parametres;i++)
           printf("%s(%c,)",nom,parametres[i]);
        }
    Ne fait absolument pas ce que tu veux... Compte le nombre de sscanf et le nombre de printf...

    Jc

  19. #19
    Membre habitué
    Inscrit en
    Septembre 2005
    Messages
    747
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 747
    Points : 174
    Points
    174
    Par défaut
    Ce code m'affiche:
    alors que je voudrais ceci:
    fonction(x,y,z)

    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
    113
    114
    115
    116
    117
    118
    119
    120
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include <float.h>
     
    #define VARIABLE 0
    #define FONCTION 1
     
     
    void espace(char **ligne)
    {
      while(**ligne == ' ') (*ligne)++;
    }
     
     
    /* Fonction qui gre les espaces pour les parametres des fonctions */
    void espace2(char **ligne)
    {
      while(**ligne == ' ' || **ligne == ',' ) (*ligne)++;
    }
     
     
    int analyse(char **ligne)
    {
      char *nom;
      char *parametres;
      int nb_parametres;
      int type;
      int cpt1,cpt2;
      char *mot1,*mot2;
      int i;
     
      espace(ligne);
     
      /* on est en fin de chaine */
      if(**ligne == '\0')
        {
          fprintf(stderr,"erreur\n");
          return 1;
        }
     
      /* on n'est pas en presence d'un mot */  
      if(!(isalpha(**ligne))) return 1;
     
     
      /* c'est une lettre */
      else
        {
          /* Calcule de la taille du nom de la variable */
          cpt1 = 0;
          mot1 = *ligne; 
     
     
          while( (*mot1 != '\0') && (*mot1 != ' ') )
    	{
    	  /* compter le nombre de caractere de cette variable */
    	  cpt1++;
    	  mot1++;
    	}
          nom = (char *) malloc(cpt1*sizeof(char)); 
          sscanf(*ligne,"%s",nom);
          *ligne = mot1;
        }
     
      espace(ligne);
     
     
      /* c'est une fonction */
      if(**ligne == '(')
        {
          (*ligne)++;
          espace(ligne);
          /* Calcule de la taille du tableau de parametres */
          cpt2 = 0;
          mot2 = *ligne; 
     
          while(*mot2 != ')' )
    	{
    	  /* compter le nombre de caractere de cette variable */
    	  cpt2++;
    	  mot2++;
    	  espace2(&mot2);
    	}
          if(*mot2 != ')') return 1;
     
          type = FONCTION;
          nb_parametres = cpt2;
          parametres = (char *) malloc(cpt2*sizeof(char)); 
          sscanf(*ligne,"%s",parametres);
     
          printf("%s(%c",nom,parametres[0]);
          if(nb_parametres>1)
    	{      
    	  for(i=1;i<nb_parametres;i++)
    	    printf(",%c",parametres[i]);
    	}
          printf(")");
          *ligne = mot2;
        }
     
      /* c'est une variable */
      else type = VARIABLE;
     
      return 0;
    }
     
     
    int main(void)
    {
      char *ligne = " fonction     (  x,  y ,     z )   ";
     
      if(analyse(&ligne))
        {
          fprintf(stderr,"erreur\n");
          return 1;
        }
      printf("\n");
      return 0;
    }

Discussions similaires

  1. if qui ne fait pas ce que je souhaite faire.
    Par Antoniom dans le forum Débuter avec Java
    Réponses: 3
    Dernier message: 10/12/2010, 12h04
  2. Réponses: 6
    Dernier message: 11/11/2007, 17h34
  3. Réponses: 7
    Dernier message: 10/05/2007, 15h53
  4. [Javascript] IE(page qui ne s'affiche pas alors que code html présent)
    Par Woufeigh dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 16/04/2007, 19h54
  5. [LG]Programme qui n'affiche rien
    Par ousunas dans le forum Langage
    Réponses: 4
    Dernier message: 17/02/2004, 19h38

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