Erreur de segmentation (core dumped) + encoder avec accents
Résolu/Fermé- Erreur de segmentation (core dumped) + encoder avec accents
- Erreur 0x80070643 - Accueil - Windows
- Open core legacy patcher - Accueil - MacOS
- Erreur 0x80070643 Windows 10 : comment résoudre le problème de la mise à jour KB5001716 - Accueil - Windows
- E avec accent - Guide
- Core temp - Télécharger - Divers Utilitaires
4 réponses
Il y a des choses bizarres dans cette fonction:
+ Pourquoi mettre les pointeurs right et left à NULL quand tu trouves?
+ Pourquoi strlen > 2? J'aurais cru > 0 puisque tu as des chaînes vides ""
Je ne peux pas traduire "tu" en "you" ?
+ On dirait que ton arbre est ordonné de deux façons. (français ou anglais).
Dans la seconde partie, c'est incohérent. Tu testes d'abord le mot français et tu passes aux traductions anglaises.
if (strlen(trad_anglais)>2){
if(strcmp(mot_francais,A->mot_francais)==0) {
... et tu passes en anglais.
+ On ne sait pas si les chaînes correspondant aux mots dans l'arbre sont correctes ou NULL.
Je te suggère d'essayer d'afficher tout ton arbre de façon récursive: gauche milieu droite
Si ça plante, tu devrais pouvoir trouver ce qui manque (un noeud ou une chaîne)
Pour les lettres accentuées, on ne sait pas dans quel code tu es: latin-1 ou utf-8, etc.
Dans certains cas, les lettres accentuées peuvent prendre plus d'un octet. Si ton mot est long, tu pourrais dépasser tes 20 caractères.
> J'avais mis ça pour tenter de résoudre le soucis, j'ai souvent du mal à comprendre d'où viennent les erreurs de segmentation. Et puisque je n'ai pas besoin
> de gauche et droite dans ma sortie de fonction, je me suis dit que ce n'était pas grave.
En faisant ça, tu détruis littéralement ton arbre. Mais je ne crois pas que c'est la cause du Segmentation fault.
Je n'avais pas remarqué, mais c'est un ABR équilibré ...
Dans ta fonction d'affichage, tu affiches d'abord le noeud courant, puis la branche gauche et la branche droite.
Normalement, on affiche d'abord la gauche, le noeud et la droite.
On voit mieux ainsi si c'est en ordre.
Les fonctions de rotations sont normalement assez complexes. Le problème est peut-être là.
Si tu peux faire des tests en insérant des éléments fictifs et si tu affiches à mesure, tu trouveras sans doute.
Tu les choisis pour pouvoir contrôler toi-même la position.
Par exemple, tu places "mm" au début, puis "aa" ou "zz" ou tout autre chose pour mieux contrôler.
Dans ta rotation droite:
y->right = N;
Qui te dis que y n'est pas NULL puisque tu effaces des liens?
En insérant à la main, j'obtiens bien un arbre trié et la fonction affiche bien comme il faut l'arbre. Cependant lorsque c'est la fonction chargementDonnee qui le fait, j'ai l'impression qu'il n'y a qu'une seule chose qui s'enregistre dans l'arbre, pourtant je fais la même chose qu'à la main mais en boucle.
Je n'arrive pas à comprendre le problème, ça serait la sortie des données via le tableau ? Ou ma boucle qui est mal faite ?
J'ai corrigé ma fonction d'affichage en affichant dans l'ordre que tu m'as indiqué.
Je n'ai pas analysé en détail, mais je trouve étrange que dans la fonction ajoutNoeud, tu retournes directement rotationDroite ou rotationGauche. dans certains cas
Qui va recevoir ce pointeur? Est-ce que ça remonte à la racine?
À moins que ton fichier soit très gros, tu pourrais afficher les lignes du fichier et l'arbre après chaque ajout dans chargementDonnee.
Je viens de d'afficher comme tu me l'as conseiller. C'était un peu compliqué à lire car j'ai 580 mots et quelques, mais j'ai donc pu remarquer de 1/ que mon arbre de ne retourner que le dernier Noeud A traité, et ne renvoyer donc jamais l'arbre entier (donc A->right et A->left ne sont vraisemblablement pas renvoyé), car dans la fonction, l'arbre s'affiche en entier, mais pas à l'extérieur.
De 2/ j'ai pu voir que l'arbre arrêté de s'agrandir au 380e mot alors que j'en ai 587, comment expliquer cela ? Je n'ai pas pourtant pas l'impression d'avoir fait d'erreur dans ma boucle while.
Tu as défini chargementDonnee avec une valeur de retour, mais tu ne l'assignes à rien.
Si ton arbre est bon avant le retour, c'est la cause de ton premier problème.
Je soupçonne encore tes retours des rotations.
Peux-tu générer des séquences de 2 lettres comme "aa", "ab", "ac", etc.
Et tu les entres dans cet ordre. Tu devrais forcer des rotations.
Fais-le à l'envers pour la symétrie: "zz", "zy", ...
Ou si tu veux générer des chaînes de chiffres avec rand()%1000 (0 à999) et tu en fait une chaîne avec un ssprintf("%03d" ... par exemple.
J'ai corrigé et en effet je n'ai plus de problème. J'ai re testé mes rotations avec une cinquantaine de doubles lettres et triples lettres, aucun soucis, tout s'équilibre comme il faut.
Je viens juste de voir que lorsque je recherchai en anglais ça ne fonctionnait pas car je triais en français, j'ai modifié un peu et ça fonctionne toujours, mais trie selon les langues.
#include <SDL2/SDL.h> #include <stdio.h> #include <SDL2/SDL_image.h> #include <stdlib.h> #include <time.h> #define G_MAX_LEN_WORDS 20 #define G_MAX_WORDS 587 // Créer un Noeud struct Noeud { char trad_anglais[20]; char mot_francais[20]; char lien_image[50]; struct Noeud *left; struct Noeud *right; }; //int max(int a, int b); int max(int a, int b) { return (a > b) ? a : b; } // Calcul hauteur int HauteurArbre(struct Noeud *N) { if (N == NULL) return -1; else return max(HauteurArbre(N->left),HauteurArbre(N->right))+1; } // Create a Noeud struct Noeud *CreerNoeud(char trad_anglais[],char mot_francais[], char lien_image[]) { struct Noeud *Noeud = (struct Noeud *) malloc(sizeof(struct Noeud)); strcpy(Noeud->trad_anglais,trad_anglais); strcpy(Noeud->mot_francais,mot_francais); strcpy(Noeud->lien_image,lien_image); Noeud->left = NULL; Noeud->right = NULL; return (Noeud); } // Right rotate struct Noeud *rotationDroite(struct Noeud *N) { struct Noeud *y = N->left; struct Noeud *N2 = y->right; y->right = N; N->left = N2; return y; } // Left rotate struct Noeud *rotationGauche(struct Noeud *N) { struct Noeud *y = N->right; struct Noeud *N2 = y->left; y->left = N; N->right = N2; return y; } // Get the balance factor int ecart(struct Noeud *N) { if (N == NULL) return 0; return HauteurArbre(N->left)-HauteurArbre(N->right); } // Insert Noeud struct Noeud *ajoutNoeud(struct Noeud *Noeud,char trad_anglais[],char mot_francais[], char lien_image[],char choixL[]) { // place le nouveau Noeud au bon endroit if (Noeud == NULL) return (CreerNoeud(trad_anglais,mot_francais,lien_image)); //fr if (strcmp(choixL,"FR")==0){ if (strcmp(mot_francais,Noeud->mot_francais)<0) Noeud->left = ajoutNoeud(Noeud->left,trad_anglais,mot_francais,lien_image,choixL); else if (strcmp(mot_francais,Noeud->mot_francais)>0) Noeud->right = ajoutNoeud(Noeud->right,trad_anglais,mot_francais,lien_image,choixL); else return Noeud; //équilibrage int balance = ecart(Noeud); if (balance > 1 && strcmp(mot_francais,Noeud->left->mot_francais)<0) return rotationDroite(Noeud); if (balance < -1 && strcmp(mot_francais,Noeud->right->mot_francais)>0) return rotationGauche(Noeud); if (balance > 1 && strcmp(mot_francais,Noeud->left->mot_francais)>0) { Noeud->left = rotationGauche(Noeud->left); return rotationDroite(Noeud); } if (balance < -1 && strcmp(mot_francais,Noeud->right->mot_francais)<0) { Noeud->right = rotationDroite(Noeud->right); return rotationGauche(Noeud); } } //en else{ if (strcmp(trad_anglais,Noeud->trad_anglais)<0) Noeud->left = ajoutNoeud(Noeud->left,trad_anglais,mot_francais,lien_image,choixL); else if (strcmp(trad_anglais,Noeud->trad_anglais)>0) Noeud->right = ajoutNoeud(Noeud->right,trad_anglais,mot_francais,lien_image,choixL); else return Noeud; //équilibrage int balance = ecart(Noeud); if (balance > 1 && strcmp(trad_anglais,Noeud->left->trad_anglais)<0) return rotationDroite(Noeud); if (balance < -1 && strcmp(trad_anglais,Noeud->right->trad_anglais)>0) return rotationGauche(Noeud); if (balance > 1 && strcmp(trad_anglais,Noeud->left->trad_anglais)>0) { Noeud->left = rotationGauche(Noeud->left); return rotationDroite(Noeud); } if (balance < -1 && strcmp(trad_anglais,Noeud->right->trad_anglais)<0) { Noeud->right = rotationDroite(Noeud->right); return rotationGauche(Noeud); } } return Noeud; } // Print the tree void printPreOrder(struct Noeud *root) { if (root != NULL) { printPreOrder(root->left); printf("f=%s \n", root->mot_francais); printf("a=%s \n", root->trad_anglais); printf("l=%s \n", root->lien_image); printPreOrder(root->right); } else{ EXIT_SUCCESS; } } char** chargementMotFR(){ char tmp[90]; FILE * fichier=fopen("mot.csv","r"); // La zone de travail (le damier) char* work = malloc(G_MAX_WORDS * (G_MAX_LEN_WORDS + 1) * sizeof(*work)); if (work == NULL) return NULL; // Les pointeurs pointant vers chaque "mot" de la zone de travail char** tabs=malloc(G_MAX_WORDS * sizeof(*tabs)); if (tabs == NULL) { free(work); return NULL; } // Nécessité de faire pointer chaque "pointeur" vers la bonne position dans le damier for (size_t i=0; i < G_MAX_WORDS; i++) tabs[i]=work + i * (G_MAX_LEN_WORDS + 1); // Remplissage int cpt=0; if (fichier==NULL) printf("Erreur d'ouverture de fichier"); else{ while (fgets(tmp,90,fichier)!=NULL){ char * pch=strtok(tmp,","); char * tmpS; while (pch!=NULL){ tmpS=strtok(pch," "); strcpy(tabs[cpt],tmpS); pch=strtok(NULL,","); } cpt++; } } return tabs; } struct Noeud * chargementDonnee(struct Noeud* A,char choixL[]){ char tmp[90]; char fr[20],en[20],lien[50]; FILE* fichier=fopen("mot.csv","r"); if (fichier==NULL) printf("Erreur d'ouverture de fichier \n"); else { while(fgets(tmp,90,fichier)!=NULL){ for (int i=0; i<strlen(tmp);i++) { if (tmp[i]==',') tmp[i]=' '; } sscanf(tmp,"%s%s%s",fr,en,lien); printf("ccccccccccccc %s %s %s \n",fr,en,lien); A=ajoutNoeud(A,en,fr,lien,choixL); //printPreOrder(A); } } return A; } struct Noeud* RechercheArbre2(struct Noeud *A, char trad_anglais[], char mot_francais[]){ if (A==NULL){ printf("NULL"); return A; } if (strlen(mot_francais)>1){ printf("non \n"); if(strcmp(mot_francais,A->mot_francais)==0) { return A; } if(strcmp(mot_francais,A->mot_francais)>0) return RechercheArbre2(A->right,"",mot_francais); else return RechercheArbre2(A->left,"",mot_francais); } else{ if (strlen(trad_anglais)>1){ printf("oui \n"); if(strcmp(trad_anglais,A->trad_anglais)==0) { return A; } if(strcmp(trad_anglais,A->trad_anglais)>0) return RechercheArbre2(A->right,trad_anglais,""); else return RechercheArbre2(A->left,trad_anglais,""); } } } char* choixLangue(){ static char choix[3]; printf("Veuillez choisir entre Anglais en tapant EN et Français en tapant FR \n"); scanf("%s",choix); return choix; } char* motChoisi(){ static char mot[20]; printf("Veuillez tapez un mot dans la langue choisie \n"); scanf("%s",mot); return mot; } int rechercheMOT2J(char** motFR,char elem[]){ for (int i=0;i<=G_MAX_WORDS-1;i++){ if (strcmp(elem,motFR[i])==0) return i; } return -1; } int nbrJoueur(){ int r=0; while (r!=1 || r!=2){ printf("Combien de joueur entre 1 et 2 ?"); scanf("%d",&r); } return r; } int main(int argc, char** argv){ //chargement struct Noeud *ArbreP=calloc(1,sizeof(struct Noeud)); struct Noeud *ArbreTmp=calloc(1,sizeof(struct Noeud)); char ** motsFR=chargementMotFR(); //choix langue/mot/joueur char choixL[5]; char motDemande[20]; //int nbrJ=nbrJoueur(); strcpy(choixL,choixLangue()); ArbreP=chargementDonnee(ArbreP,choixL); printPreOrder(ArbreP); strcpy(motDemande,motChoisi()); if (strcmp(choixL,"EN")==0){ printf("Entre dans EN \n"); ArbreTmp=RechercheArbre2(ArbreP,motDemande,"1"); printPreOrder(ArbreTmp); if (ArbreTmp==NULL){ while (ArbreTmp==NULL){ printf("Mot non disponible \n"); strcpy(motDemande,motChoisi()); ArbreTmp=RechercheArbre2(ArbreP,motDemande,"1"); } } } if (strcmp(choixL,"FR")==0){ printf("Entre dans FR \n"); long int retour=rechercheMOT2J(motsFR,motDemande); printf("retour:%ld \n",retour); printf("e1 \n"); if (retour<0){ while (retour<0){ printf("Mot non disponible \n"); strcpy(motDemande,motChoisi()); retour=rechercheMOT2J(motsFR,motDemande); } } printf("mot:%s \n",motsFR[retour]); printf("e2 \n"); ArbreTmp=RechercheArbre2(ArbreP,"1",motsFR[retour]); //printPreOrder(ArbreTmp); } //image if (SDL_Init(SDL_INIT_VIDEO)!=0){ fprintf(stdout,"Echec %s \n",SDL_GetError()); return -1; } SDL_Window *pWindow=NULL; SDL_Rect dstrect={5,5,120,120}; if (0!=SDL_Init(SDL_INIT_VIDEO)){ printf("Erreur init %s \n",SDL_GetError()); } pWindow=SDL_CreateWindow("Jeu",SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,1280,720,SDL_WINDOW_SHOWN); if (NULL==pWindow){ printf("Erreur create %s \n",SDL_GetError()); } SDL_Renderer *render = SDL_CreateRenderer(pWindow, -1 ,0); SDL_Rect r; r.x=50; r.y=50; r.w=50; r.h=50; SDL_SetRenderDrawColor(render,255,0,0,255); SDL_Surface *fond =IMG_Load("akastuki.png"); char * tmpM=(char *)malloc(strlen(ArbreTmp->lien_image)*sizeof(char)); strcpy(tmpM,ArbreTmp->lien_image); printf("%s \n",ArbreTmp->lien_image); printf("%s \n",tmpM); SDL_Surface *image =IMG_Load(tmpM); free(tmpM); if(!fond || !image){ printf("erreur fichier image %s\n",SDL_GetError()); } SDL_Texture *texture=SDL_CreateTextureFromSurface(render,fond); SDL_Texture *texture2=SDL_CreateTextureFromSurface(render,image); SDL_RenderFillRect(render,&r); SDL_RenderPresent(render); if(!texture||!texture2){ printf("erreur texture %s \n",SDL_GetError()); } if (pWindow){ SDL_RenderCopy(render,texture,NULL,NULL); SDL_RenderCopy(render,texture2,NULL,&dstrect); SDL_RenderPresent(render); SDL_Delay(3000); SDL_DestroyWindow(pWindow); SDL_FreeSurface(fond); SDL_DestroyTexture(texture); SDL_DestroyRenderer(render); SDL_FreeSurface(image); SDL_DestroyTexture(texture2); } else{ printf("Erreur création de la fenêtre :%s\n",SDL_GetError()); } SDL_Quit(); return 0; }
J'obtiens ça au final.
Merci pour ton aide !
Modifié le 10 déc. 2022 à 16:42
J'avais mis ça pour tenter de résoudre le soucis, j'ai souvent du mal à comprendre d'où viennent les erreurs de segmentation. Et puisque je n'ai pas besoin de gauche et droite dans ma sortie de fonction, je me suis dit que ce n'était pas grave.
J'avais mis >2 par question de sécurité avec les caractères invisibles, mais il est vrai qu'ils ne sont pas comptés.
Merci de m'avoir remarqué l'erreur :
if (strlen(trad_anglais)>2){
if(strcmp(mot_francais,A->mot_francais)==0) {
Je n'avais pas du tout vu.
Pour l'affichage récursif de mon arbre, j'ai la fonction printPreOrder, mais j'ai l'impression qu'il y a un problème : elle m'affiche d'abord des choses vides, puis d'un coup un endroit de mon arbre, mais je ne pense pas la fin car ce n'est pas les derniers données de mon CSV.
Fichier en question : https://www.mediafire.com/file/8crb8luaio7i6kq/mot.csv/file
Je crois que les données de base sont entrées en UTF-8 mais je ne suis pas sûr.
J'ai essayé d'actualiser le code avec tes conseils :
Modifié le 10 déc. 2022 à 16:43
Ok je viens de comprendre mon erreur de segmentation. Je l'ai corrigé dans mon message du dessus. Maintenant mon seul problème est l'encryptage des mots.