J'ai écrit un code qui devrait normalement vérifier si une expression est bien formée (les parenthèses ouvrante et fermante sont toutes deux présentes) ou non ( il n'y en a qu'une). Mais dans le cas ou une parenthèse manque ca me renvoie toujours que l'expression est valide, d'où mon problème.😫😫
Est ce que quelqu'un peut me montrer l'erreur que j'ai commise🙏🙏? Voici mon code:
#include <stdio.h>
#include<stdlib.h>
#include<string.h>
#define N 10
typedef struct pile pile;
struct pile
{
int sommet;
char tab[N];
};
void init(pile p){
p.sommet=0;
}
int P_pleine(pile p){
int pleine;
if (p.sommet==N)
{
pleine=1;
}
else{
pleine=0;
}
return pleine;
}
int P_vide(pile p){
int vide;
if (p.sommet==0)
{
vide=1;
}
else{
vide=0;
}
return vide;
}
void empiler(pile p, char x){
if (P_pleine(p)==1)
{
printf("Pile pleine!\n");
}
else{
p.sommet=p.sommet+1;
p.tab[p.sommet]=x;
}
}
void depiler(pile p){
if (P_vide(p)==1)
{
printf("Pile vide.\n");
}
else{
p.sommet=p.sommet-1;
}
}
int parenthese(char* expression){
int a,b;
pile p;
init(p);
for (int i = 0; i < sizeof(expression); i++)
{
if(expression[i]=='(')
{
empiler(p,expression[i]);
}
else{
if(expression[i]==')'){
if (P_vide==0)
{
depiler(p);
}
else
a=-1;
}
}
}
if (P_vide(p)==1)
{
a=1;
}
else{
a=-1;
}
return a;
}
void main(){
char A[]={"(2+4*2"};
printf("\n\nL'expression ");
printf("%s",A);
printf(" est :\t");
bienforme(A);
}
Il faut activer les warnings et en prendre compte (chose que j'ai faite avant même de lire ton code) :
$ gcc -Wall -Wextra -fanalyzer -o par par.c
par.c: In function ‘init’:
par.c:14:16: warning: parameter ‘p’ set but not used [-Wunused-but-set-parameter]
14 | void init(pile p){
| ~~~~~^
par.c: In function ‘parenthese’:
par.c:72:23: warning: comparison of integer expressions of different signedness: ‘int’ and ‘long unsigned int’ [-Wsign-compare]
72 | for (int i = 0; i < sizeof(expression); i++)
| ^
par.c:80:27: warning: the comparison will always evaluate as ‘false’ for the address of ‘P_vide’ will never be NULL [-Waddress]
80 | if (P_vide==0)
| ^~
par.c:66:11: warning: unused variable ‘b’ [-Wunused-variable]
66 | int a,b;
| ^
par.c: At top level:
par.c:102:6: warning: return type of ‘main’ is not ‘int’ [-Wmain]
102 | void main(){
| ^~~~
par.c: In function ‘main’:
par.c:108:5: warning: implicit declaration of function ‘bienforme’ [-Wimplicit-function-declaration]
108 | bienforme(A);
| ^~~~~~~~~
/usr/bin/ld: /tmp/ccC6RnYG.o: in function `main':
par.c:(.text+0x274): undefined reference to `bienforme'
collect2: error: ld returned 1 exit status
Il va falloir corriger tout ça.
N'oublie pas que tous les passages de paramètres se font par copie, donc ta fonction init va modifier une copie de ta pile pas ta pile … il faut revoir le chapitre des pointeurs.
Il faut écrire bienforme ! on ne va pas le faire à ta place.
As-tu au moins l'algo avant de vouloir pisser du code ?
Regarde bien ton cours C, tu devrais y trouver le prototype correct pour main :
int main(void)
{
...
ton code
...
}
Sur ta méthode
Alors utiliser une pile, à moins que cela ne te sois demandé, est un peu overkill. Il suffit d'incrémenter un compteur sur une parenthèse ouvrante et vérifier lors d'une parenthèse fermante s'il y a eu au moins une ouvrante auparavant, si le compteur est à 0 c'est que l'expression est mal formée sinon tu décrémentes et tu continues.
Utilise le debugger et au pas à pas tu vois ce qu'il se passe.
En tout cas tu passe ta structure en paramètre sans pointeur donc chaque fonction reçoit sa copie de la structure et tu "perds" les changements au niveau de l'appelant.
git is great because Linus did it, mercurial is better because he didn't.
Il faut activer les warnings et en prendre compte (chose que j'ai faite avant même de lire ton code) :
$ gcc -Wall -Wextra -fanalyzer -o par par.c
par.c: In function ‘init’:
par.c:14:16: warning: parameter ‘p’ set but not used [-Wunused-but-set-parameter]
14 | void init(pile p){
| ~~~~~^
par.c: In function ‘parenthese’:
par.c:72:23: warning: comparison of integer expressions of different signedness: ‘int’ and ‘long unsigned int’ [-Wsign-compare]
72 | for (int i = 0; i < sizeof(expression); i++)
| ^
par.c:80:27: warning: the comparison will always evaluate as ‘false’ for the address of ‘P_vide’ will never be NULL [-Waddress]
80 | if (P_vide==0)
| ^~
par.c:66:11: warning: unused variable ‘b’ [-Wunused-variable]
66 | int a,b;
| ^
par.c: At top level:
par.c:102:6: warning: return type of ‘main’ is not ‘int’ [-Wmain]
102 | void main(){
| ^~~~
par.c: In function ‘main’:
par.c:108:5: warning: implicit declaration of function ‘bienforme’ [-Wimplicit-function-declaration]
108 | bienforme(A);
| ^~~~~~~~~
/usr/bin/ld: /tmp/ccC6RnYG.o: in function `main':
par.c:(.text+0x274): undefined reference to `bienforme'
collect2: error: ld returned 1 exit status
Il va falloir corriger tout ça.
N'oublie pas que tous les passages de paramètres se font par copie, donc ta fonction init va modifier une copie de ta pile pas ta pile … il faut revoir le chapitre des pointeurs.
Il faut écrire bienforme ! on ne va pas le faire à ta place.
As-tu au moins l'algo avant de vouloir pisser du code ?
Regarde bien ton cours C, tu devrais y trouver le prototype correct pour main :
int main(void)
{
...
ton code
...
}
Sur ta méthode
Alors utiliser une pile, à moins que cela ne te sois demandé, est un peu overkill. Il suffit d'incrémenter un compteur sur une parenthèse ouvrante et vérifier lors d'une parenthèse fermante s'il y a eu au moins une ouvrante auparavant, si le compteur est à 0 c'est que l'expression est mal formée sinon tu décrémentes et tu continues.
Moi aussi, j'ai l'impression d'avoir loupé quelque chose. @White Crow: je ne pense pas que tes remarques étaient méchantes. Si on ignore les warning du compilateur, on s'expose à n'importe quoi.
Le Tout est souvent plus grand que la somme de ses parties.
@White Crow tu as raison, il me faut relire les pointeurs. C'est là-bas ou tout coince. Et tes remarque ne sont pas méchantes. Je débute en programmation et j'ai voulu directement implémenter l'exercice en C, sans d'abord passer par l'algorithme. Je ne maitrise pas encore assez de choses comme je le pensais, je vais juste aller refaire des recherches.
Les opération empiler et dépiler doivent modifier l'état de la pile. Mais là, ce qui est passé en paramètre c'est une _copie_ de la pile (c'est une différence avec d'autres langages comme Java, PHP, Python, Javascript, ...)
(*) sûrement, même.
- Edité par michelbillaud 14 juin 2021 à 19:31:58
expression bien formée
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
git is great because Linus did it, mercurial is better because he didn't.
Le Tout est souvent plus grand que la somme de ses parties.
Le Tout est souvent plus grand que la somme de ses parties.
Le Tout est souvent plus grand que la somme de ses parties.