bonjour j ai commence le tp jeu de pendu , j ai essaye d executer un code ms il n a pas fonctionne .veuillez me guider vers l erreur merci d avance et merci d avance.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include "dico.h"
int main()
{
char* motsecret={0};
int* mot={0};
int k=0;
int lettreentree=0;
motsecret=malloc(sizeof(char)*strlen(motsecret));
motsecret=aleatoire();
mot=malloc(sizeof(int)*strlen(motsecret));
if(mot==NULL)
exit(0);
for(int j=0;j<strlen(motsecret);j++)
{
mot[j]=0;
}
printf("taper une lettre\n");
while(k<10&&!(mottrouve(motsecret,mot)))
{
lettreentree=lirecaractere();
for(int i=0;i<strlen(motsecret);i++)
{
if (lettreentree==motsecret[i])
mot[i]=1;
printf("%c",motsecret[i]);
printf("vs avez trouve la lettre n %d \n",i);
}
if (strchr(motsecret,lettreentree)==NULL)
k++;
free(motsecret);
free(mot);
}
if (mottrouve(motsecret,mot))
{
printf("vs avez gagne\n");
}}
int mottrouve(char motsecret[],int mot[])
{ int compteur=0;
for (int h=0;h<strlen(motsecret);h++)
{
if (mot[h]==0)
{
compteur++;
}
}
if (compteur!=0)
return 0;
else
return 1;
}
char lirecaractere()
{
char caractere=getchar();
caractere=toupper(caractere);
while(caractere!='\n');
return caractere;
}
char* aleatoire()
{
int caractere=0;int nombredemots=0;int numerodeligne=0; char* motpioche={0};
FILE* fichier=NULL;
int compteurb=0;
fichier=fopen("dico.c","r");
if(fichier==NULL)
{
printf("imposible de telecharger le fichier");
return 0;
}
rewind(fichier);
do {caractere=fgetc(fichier);
if(caractere=='\n')
{
nombredemots++;
}
}while(caractere!=EOF);
numerodeligne=rand()%nombredemots;
while (compteurb<numerodeligne)
{
rewind(fichier);
motpioche=fgets(motpioche,100,fichier);
motpioche[strlen(motpioche)-1]='\0';
compteurb++;
}
fclose(fichier);
return motpioche;
}
Ensuite, un second conseil : lire les messages du compilateurs, au cas où rajouter les options de compilations qui permettent de les avoir (-Wall -Wextra pour gcc et clang).
@White Crow: as-tu lu le code? Il y a plein d'erreurs fondamentales. @NouhaylaZakaria: Je te suggère de faire une version plus simple de ton programme dans laquelle tu fournis le mot mystère directement. Après seulement, tu pourras t'essayer avec un fichier. Comment peux-tu connaître la longueur à réserver par malloc pour le mot mystère si tu ne sais pas lequel tu vas choisir? Si tu fais deux appels à malloc, ça vaut peut-être la peine de faire une fonction où tu vérifies si ça marche. etc.
Le Tout est souvent plus grand que la somme de ses parties.
merci pierre j ai deja essaye avec la version simple ms elle n a pas marche voici le code
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
char lireCaractere();
int main()
{
int k=0;
char mot[7]="******";
const char motsecret[7]="MARRON";
while (((strcmp(mot,motsecret)!=0)&&(k<10)))
{
int maLettre;
maLettre = lireCaractere();
for(int i=0;i<7;i++)
{
if(maLettre==motsecret[i])
{
mot[i]=maLettre;
printf("%s\n",mot);
}
}
if (strchr(motsecret,maLettre)==NULL)
{
k++;}
}
if(strcmp(mot,motsecret)==0)
{
printf("vs avez trouvez le mot");
}
else
{
printf("malheureusement vs n avez pas trouve le mot");
}
printf("%s",mot);
return 0;
}
char lireCaractere()
{
char caractere = 0;
caractere = getchar(); // On lit le premier caractère
caractere = toupper(caractere); // On met la lettre en majuscule si elle ne l'est pas déjà
// On lit les autres caractères mémorisés un à un jusqu'au \n (pour les effacer)
while (getchar() != '\n') ;
return caractere; // On retourne le premier caractère qu'on a lu
}
et stp tu peux me guider vers ces erreurs fondamentales
- Edité par NouhaylaZakaria 2 septembre 2021 à 22:12:49
Tu peux commencer par corriger les erreurs signalées par le compilateur :
truc.c:5:7: error: conflicting types for ‘strchr’
5 | char* strchr(const char* ch,const char* caractereachercher);
| ^~~~~~
In file included from truc.c:4:
/usr/include/string.h:226:14: note: previous declaration of ‘strchr’ was here
226 | extern char *strchr (const char *__s, int __c)
| ^~~~~~
truc.c: In function ‘main’:
truc.c:14:24: warning: comparison with string literal results in unspecified behavior [-Waddress]
14 | while ((k<10)&&(mot!="MARRON"))
| ^~
truc.c:33:26: warning: passing argument 2 of ‘strchr’ makes pointer from integer without a cast [-Wint-conversion]
33 | if (strchr(motsecret,maLettre)==NULL)
| ^~~~~~~~
| |
| int
truc.c:5:7: note: expected ‘const char *’ but argument is of type ‘int’
5 | char* strchr(const char* ch,const char* caractereachercher);
| ^~~~~~
truc.c:38:15: warning: comparison with string literal results in unspecified behavior [-Waddress]
38 | if(mot=="MARRON")
| ^~
Ligne 5 : tu as déclaré une fonction qui était déjà déclarée.
Ligne 14 : tu compares deux chaînes avec '!=', c'est une erreur classique (une chaîne de caractères étant un tableau, on ne peut pas utiliser '==' et '!='). Même erreur ligne 38.
Ligne 33 : tu as passé en paramètre un entier au lieu d'une chaîne de caractères.
@White Crow: as-tu lu le code? Il y a plein d'erreurs fondamentales.
Non. Les messages du genre «j'ai une erreur dans mon code dites moi où elle est» sans plus de détails ou d'implication ne me donnent pas envie d'investir du temps.
Il n'y a même pas la description du problème ! et ma boule de cristal est cassée …
Si le PO ne fait pas un minimum d'efforts c'est pas la peine, enfin àmha.
OK donne nous le code qui fonctionne. On pourra voir si on peut améliorer avant de continuer. Tu peux tester en parallèle de lire le fichier dictionnaire et d'essayer d'afficher les 10 premiers mots. Ensuite, génère un nombre aléatoire entre 0 et 10 et affiche seulement ce mot. Après on pourra parler sérieusement.
Le Tout est souvent plus grand que la somme de ses parties.
oui j ai modifie le code sinon voici le nouveau programme et j ai essaye de faire un programme qui lit un mot du fichier mais il ne fonctionne pas
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
char lireCaractere();
int main()
{
int k=0;
char mot[7]="******";
const char motsecret[7]="MARRON";
while (((strcmp(mot,motsecret)!=0)&&(k<10)))
{
int maLettre;
maLettre = lireCaractere();
for(int i=0;i<7;i++)
{
if(maLettre==motsecret[i])
{
mot[i]=maLettre;
printf("%s\n",mot);
}
}
if (strchr(motsecret,maLettre)==NULL)
{
k++;}
}
if(strcmp(mot,motsecret)==0)
{
printf("vs avez trouvez le mot");
}
else
{
printf("malheureusement vs n avez pas trouve le mot");
}
printf("%s",mot);
return 0;
}
char lireCaractere()
{
char caractere = 0;
caractere = getchar(); // On lit le premier caractère
caractere = toupper(caractere); // On met la lettre en majuscule si elle ne l'est pas déjà
// On lit les autres caractères mémorisés un à un jusqu'au \n (pour les effacer)
while (getchar() != '\n') ;
return caractere; // On retourne le premier caractère qu'on a lu
}
- Edité par NouhaylaZakaria 3 septembre 2021 à 18:31:10
Tu peux sauver du code en assignant en même temps que tu déclares: int lettreentree = lirecaractere(); Il y a des parenthèses inutiles: while (((strcmp(mot,motsecret)!=0)&&(k<10))) Tu n'est pas obligé d'entourer chaque sous-expression. Je pense que ce serait mieux avec un do {...} while plutôt qu'un while {...}. Tu dois passer au moins une fois dans la boucle. Pour éviter l'appel à strchr, je ferais ceci: + juste avant la boucle pour chercher si le caractère est dans le mot mystère, je ferais n=1; si je trouve une occurence (ou plus) de la lettre, je fais n=0; dans le if(...) Après la fin de boucle, je fais k += n; qui augmentera seulement si on n'a pas trouvé la lettre. À la fin de la boucle do ... while, je pense que ce serait mieux de tester si k>=10 plutôt que d'appeler strcmp une autre fois. Tu pourrais te préparer pour la suite en testant la longueur du mot mystère au début et réserver avec malloc l'espace pour mot. Ensuite tu mets des '*' dans mot, suivi d'une fin de schaîne ('\0') - Pour la fonction aleatoire(): pas besoin de rewind avant le premier passage. tu ne réserves aucun espace pour la variable pioche, tu devras le faire après le premier passage. Pour savoir comment d'espace réserver, tu comptes le nombre de caractères dans chaque mot (incluant le '\n' et tu trouve la longueur maximum. C'est celle là que tu utiliseras pour pioche (ne pas oublier une position pour le '\0') C'est également cette valeur que tu utiliseras dans le fgerts() Il faut appeler srand() avant l'appel à rand(). Ça te prendra #include <time.h> Je ne sais pas la longueur de ton dictionnaire. J'en ai un de 325000 mots et rand() ne va pas plus loin que 32767. Je ferais (rand() * 32767) % nombredelignes Ou on utilise le symbole RAND_MAX qui vaut justement 32767. Fais le close avant le return.
Le Tout est souvent plus grand que la somme de ses parties.
merci pour tes conseils pour ameliorer le premier code quant au deuxieme je pense que l erreur provient du fait que je n ai pas fait l allocation dynamique pour la variable mot[] car on ne sait pas a priori la taille du tableau donc on doit faire une allocation dynamique.N ' est ce pas?
Tu lis ton fichier deux fois, n'est-ce pas? Lors de la première lecture, tu comptes le nombre de lignes. Tu pourrais en même temps compter le nombre de caractères sur chaque ligne et tu le compare au maximum (qui sera 0 au départ). Tu obtiendra donc la longueur du mot le plus long de ton dictionnaire. Tu es certain que tous les mots lus avec fgets ensuite ne seront pas aussi long. motchoisi = fgets(motchoisi, maximum+1, file); Tu dois en effet réserver de l'espace pour le mot que tu cherches. Ce sera égal au maximum trouvé (plus 1 pour le '\0') char *motchoisi = malloc(maximum+1);
Le Tout est souvent plus grand que la somme de ses parties.
j'ai essaye d'utiliser un grand tableau mais le code ne fonctionne pas ,il renvoie(NULL) et dans le compilateur il s'est ecrit que la fonction retourne l'adresse d'une variable locale.est ce que la variable est consideree comme variable locale? est ce que le pb provient du fait qu il est locale dans la fonction lirefichier().
EDIT:est ce que je dois faire l'allocation dans la fonction main ou dans lirefichier()?
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
char* lirefichier(int* pointeurdunumchoisi);
int main()
{
int numchoisi=7;
printf("%s",lirefichier(&numchoisi));
return 0;
}
char* lirefichier(int* pointeurdunumchoisi)
{
FILE* file=NULL;
char mot[100]={0};
int k=0;
int numchoisi=0;
char caractere;
file=fopen("FILE.txt","r");
if(file==NULL)
{
printf("on ne peut pas ouvrir le fichier");
return 0;
}
else
{
rewind(file);
while(caractere!=EOF)
{
caractere=fgetc(file);
if(caractere=='\n')
{
k++;
}
}
rewind(file);
numchoisi=*pointeurdunumchoisi;
while(numchoisi>0)
{
caractere=fgetc(file);
if(caractere=='\n')
numchoisi--;
}
fgets(mot,100,file);
mot[strlen(mot)-1]='\0';
}
fclose(file);
return mot ;
}
- Edité par NouhaylaZakaria 3 septembre 2021 à 19:26:10
Tu devrais t'en tenir à ton idée de départ, ne pas mettre de paramètre à lirefichier() (moi j'aurais mis le nom du fichier à lire) Dans le main, tu déclares et assigne: char *motMystere = lirefichier(); et tu le cherches ensuite ... tu devras faire un free(motMystere) dans le main à la fin. Dans la fonction lirefichier(), si tu ne veut pas t'embêter avec la longueur maximum, réserves mot avec malloc. char *mot = malloc(100); C'est la seule façon (ou presque ...) de retourner facilement le mot trouvé au main. numchoisi doit être déterminé avec rand() Fais: srand(time(NULL)); // avec un #include <time.h> numchoisi = (rand() * RAND_MAX) % nombredemots;
Le Tout est souvent plus grand que la somme de ses parties.
merci infiniment finalement le code a marché et j 'ai combiné les deux codes précédents ,si je veux ameliorer le jeu en dessinant un bonhomme qui se fait pendre,comment y faire car je n'ai aucune idéé sur le dessin en language c,sinon voila le code final
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
char lireCaractere();
char* lirefichier();
int main()
{
int k=0;
char* motmystere=malloc(100);
motmystere=lirefichier();
char* mot=malloc(strlen(motmystere));
for(int g=0;g<strlen(motmystere);g++)
{
mot[g]='*';
}
while ((strcmp(mot,motmystere)!=0&&k<10))
{
int maLettre;
maLettre = lireCaractere();
for(int i=0;i<strlen(motmystere);i++)
{
if(maLettre==motmystere[i])
{
mot[i]=maLettre;
printf("%s\n",mot);
}
}
if (strchr(motmystere,maLettre)==NULL)
{
k++;}
}
if(strcmp(mot,motmystere)==0)
{
printf("vs avez trouvez le mot");
}
else
{
printf("malheureusement vs n avez pas trouve le mot");
}
printf("%s",motmystere);
return 0;
}
char lireCaractere()
{
char caractere = 0;
caractere = getchar(); // On lit le premier caractère
caractere = toupper(caractere); // On met la lettre en majuscule si elle ne l'est pas déjà
// On lit les autres caractères mémorisés un à un jusqu'au \n (pour les effacer)
while (getchar() != '\n') ;
return caractere; // On retourne le premier caractère qu'on a lu
}
char* lirefichier()
{
FILE* file=NULL;
int k=0;
int numchoisi=0;
char caractere;
char* mot=malloc(100);
file=fopen("kkzfz.txt","r");
if(file==NULL)
{
printf("on ne peut pas ouvrir le fichier");
return 0;
}
else
{
rewind(file);
while(caractere!=EOF)
{
caractere=fgetc(file);
if(caractere=='\n')
{
k++;
}
}
rewind(file);
srand(time(NULL));
numchoisi=rand()%k;
while(numchoisi>0)
{
caractere=fgetc(file);
if(caractere=='\n')
numchoisi--;
}
fgets(mot,100,file);
mot[strlen(mot)-1]='\0';
}
fclose(file);
return mot ;
}
- Edité par NouhaylaZakaria 3 septembre 2021 à 21:53:06
#define MAXMOT 28 // 28 à cause du caractère nul terminal
/* ... ... ... ... */
char motsecret[MAXMOT];
ou directement
char motsecret[28];
si on n'a pas encore vu les #define.
J'en profite pour dire que je n'aime pas qu'un cours adapté aux débutants encourage trop souvent la syntaxe :
char* motsecret=/* quelque chose */;
Oui elle est (en général) correcte, mais l'utilise-t-on à bon escient ? Je me souviens quand j'avais suivi le cours j'avais tendance à utiliser cette syntaxe parce qu'elle est utilisée dans le cours. Peut-être que je suis moins intelligent que la moyenne, mais au début, quand j'essayais de manipuler des chaînes de caractères définies ainsi, je me faisais avoir avec ce genre de piège :
char* motsecret1={0}; // piège : du coup le mot ne comporte qu'un caractère
char* motsecret2="machin"; // piège : du coup on ne peut plus le modifier
Pour moi, et surtout avec un langage difficile comme le C, il faut toujours savoir ce qu'on fait au moment où on le fait. Quand on déclare une chaîne de caractères avec [] ou avec *, il faut savoir pourquoi. Ici ça a un sens de le faire avec [] et une taille constante, alors que dans une fonction, le paramètre sera déclaré avec * parce qu'il y a une raison précise à ça. Ce n'est pas juste : dans le cours ils font comme ça, alors je fais pareil. En se forçant à savoir ce qu'on fait au moment où on le fait, on évite les pièges de débutants. En tout cas c'est mon expérience. Il est vrai que je ne suis toujours pas à l'aise avec les pointeurs en général. N'empêche que programmer en C ne me fait pas peur : je fais attention à ce que je fait.
Dans le main, on a les lignes: char* motmystere=malloc(100); motmystere=lirefichier(); Dans lirefichier(), tu réserves de l'espace pour le mot mystère (variable mot). Tu réserves de l'espace inutilement dans le main. Tu ne fais pas de free des espaces que tu réserves avec malloc. Tu fais dans le main: char* mot=malloc(strlen(motmystere)); Tu ne réserves pas d'espace pour la fin de chaîne ('\0'). Ça pourrait te causer des problèmes. Tu remplis le mot avec des '*' mais tu ne mets pas de '\0' (fin de chaîne) à la fin. Tu es peut-être chanceux, mais il ne faut pas présumer que l'espace réservé par malloc est initialisé à 0. Si tu ne réussis pas à ouvrir le fichier, tu fais un return 0. Je t'invite à tester avec un fichier qui n'existe pas ... Tu devrais plutôt faire exit(1); Quand tu lis le fichier pour la deuxième fois, tu utilises encore des fgetc(). Tu pourrais accélérer en faisant des fgets() toujours dans le même espace while(numchoisi >= 0) { fgets(mot,100,file); numchoisi--; } Pas besoin de le refaire en dehors de la boucle, le dernier est déjà là. Pour le dessin du pendu, je pense qu'il faudra attendre encore quelques chapitres ... - > Tu peux, mais ce n'est pas une obligation, tu pourrais utiliser un tableau suffisamment grand pour contenir le plus grand mot existant. Ça ne nous dis pas où ni comment on doit réserver. Je préfère avec malloc. On pourrait le faire avec un tableau global ou un tableau statiqque dans la fonction ou un tableau réservé par malloc et passé en paramètre à la fonction. ou bêtement déclaré dans le main et passé à la fonction en paramètre ou bien ...t
Le Tout est souvent plus grand que la somme de ses parties.
#define MAXMOT 28 // 28 à cause du caractère nul terminal
/* ... ... ... ... */
char motsecret[MAXMOT];
ou directement
char motsecret[28];
si on n'a pas encore vu les #define.
J'en profite pour dire que je n'aime pas qu'un cours adapté aux débutants encourage trop souvent la syntaxe :
char* motsecret=/* quelque chose */;
Oui elle est (en général) correcte, mais l'utilise-t-on à bon escient ? Je me souviens quand j'avais suivi le cours j'avais tendance à utiliser cette syntaxe parce qu'elle est utilisée dans le cours. Peut-être que je suis moins intelligent que la moyenne, mais au début, quand j'essayais de manipuler des chaînes de caractères définies ainsi, je me faisais avoir avec ce genre de piège :
char* motsecret1={0}; // piège : du coup le mot ne comporte qu'un caractère
char* motsecret2="machin"; // piège : du coup on ne peut plus le modifier
Pour moi, et surtout avec un langage difficile comme le C, il faut toujours savoir ce qu'on fait au moment où on le fait. Quand on déclare une chaîne de caractères avec [] ou avec *, il faut savoir pourquoi. Ici ça a un sens de le faire avec [] et une taille constante, alors que dans une fonction, le paramètre sera déclaré avec * parce qu'il y a une raison précise à ça. Ce n'est pas juste : dans le cours ils font comme ça, alors je fais pareil. En se forçant à savoir ce qu'on fait au moment où on le fait, on évite les pièges de débutants. En tout cas c'est mon expérience. Il est vrai que je ne suis toujours pas à l'aise avec les pointeurs en général. N'empêche que programmer en C ne me fait pas peur : je fais attention à ce que je fait.
(Je dis ça juste pour exprimer une opinion.)
- Edité par robun il y a environ 14 heures
merci @robun pour tes conseils
merci @pierrelefou pour tes conseils mais est ce que tu peux m'expliquer pourquoi je dois faire exit(1) au lieu de return(0) sinon voici le code avec les modifications que tu m'as proposees
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
char lireCaractere();
char* lirefichier();
int main()
{
int k=0;
int nbredelettres;
char* motmystere;
motmystere=lirefichier();
char* mot=malloc(strlen(motmystere)+1);
for(int g=0;g<strlen(motmystere);g++)
{
mot[g]='*';
}
mot[strlen(motmystere)]='\0';
nbredelettres=strlen(motmystere);
printf("le mot a %d lettres",nbredelettres);
while ((strcmp(mot,motmystere)!=0&&k<10))
{
int maLettre;
maLettre = lireCaractere();
for(int i=0;i<strlen(motmystere);i++)
{
if(maLettre==motmystere[i])
{
mot[i]=maLettre;
printf("%s\n",mot);
}
}
if (strchr(motmystere,maLettre)==NULL)
{
k++;}
}
if(strcmp(mot,motmystere)==0)
{
printf("vs avez trouvez le mot");
}
else
{
printf("malheureusement vs n avez pas trouve le mot");
}
printf("%s",motmystere);
return 0;
}
char lireCaractere()
{
char caractere = 0;
caractere = getchar(); // On lit le premier caractère
caractere = toupper(caractere); // On met la lettre en majuscule si elle ne l'est pas déjà
// On lit les autres caractères mémorisés un à un jusqu'au \n (pour les effacer)
while (getchar() != '\n') ;
return caractere; // On retourne le premier caractère qu'on a lu
}
char* lirefichier()
{
FILE* file=NULL;
int k=0;
int numchoisi=0;
char caractere;
char* mot=malloc(100);
file=fopen("kkzfz.txt","r");
if(file==NULL)
{
printf("on ne peut pas ouvrir le fichier");
exit(1);
}
else
{
rewind(file);
while(caractere!=EOF)
{
caractere=fgetc(file);
if(caractere=='\n')
{
k++;
}
}
rewind(file);
srand(time(NULL));
numchoisi=rand()%k;
while(numchoisi>0)
{
fgets(mot,100,file);
mot[strlen(mot)-1]='\0';
numchoisi--;
}
}
fclose(file);
return mot ;
}
- Edité par NouhaylaZakaria 4 septembre 2021 à 20:51:30
Dans la ligne: char* mot=malloc(strlen(motmystere)); Tu ne réserves pas un espace pour le '\0'. Il faut réserver un espace de plus. Pourquoi le exit(1) si on ne peut pas ouvrir le fichier? Le return dans le main retourne au système. Mais le return dans la fonction retourne au main, là où tu t'attends à un pointeur vers le mot mystère. C'est comme si tu retournais un pointeur NULL. Tu auras une erreur du genre "segmentation fault" Le exit(1) retourne directement au système.
Le Tout est souvent plus grand que la somme de ses parties.
Tu mets bien un '\0' dans la dernière position, mais tu ne la réserves pas: char* mot=malloc(strlen(motmystere) + 1); // c'est le +1 qui te manques. Le exit() retourne un code au système qui peut être vérifié par ce dernier ou par des commandes exécutées en batch. exit(0) indique qu'il n'y a pas d'erreur. exit(1) retourne le code d'erreur 1.
Le Tout est souvent plus grand que la somme de ses parties.
pour que ce soit plus facilement lisible on peut utiliser les macros EXIT_SUCCESS et EXIT_FAILURE en lieu et place de 0 et 1 … c'est même un peu plus portable. Elles sont définies dans le header stdlib.
× 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.
Le Tout est souvent plus grand que la somme de ses parties.
et stp tu peux me guider vers ces erreurs fondamentales
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.
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.
Le Tout est souvent plus grand que la somme de ses parties.