Problème programme

Résolu
jamsss Messages postés 36 Date d'inscription   Statut Membre Dernière intervention   -  
jamsss Messages postés 36 Date d'inscription   Statut Membre Dernière intervention   -
Bonjour,

J'ai écrit ce code en c, et j'ai un soucis pour remplir un tableau de pointeurs de chaînes, gcc ne me donne aucune erreur mais la compilation me donne une erreur de segmentation (sûrement parce que le tableau reste vide...)

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

short dichotomie(char **dico,char *mot,short nb_mots);
void purger();
int main()
{
char *mot;
int nb_mots,i;
mot=malloc(30*sizeof(char));

printf("Combien vous vous entrer de mots ? ");
scanf("%i",&nb_mots);
purger();
char *dico[nb_mots];
dico[nb_mots]=malloc(nb_mots*sizeof(char));
for (i=0;i<nb_mots;i++)
{
printf("Entrez le mot %i: ",i+1);
scanf("%s",dico[i]); /* Le problème se situe ici le tableau ne se remplit pas...*/
purger();
}
printf("Quel est le mot à comparer ? ");
scanf("%s",mot);
purger();
if (dichotomie(dico,mot,nb_mots)==1) printf("Le mot est dans le tableau");
else printf("Le mot n'est pas dans le tableau");
return 0;
}

short dichotomie(char **dico,char *mot,short nb_mots)
{
int i,j,k;
j=nb_mots;

while ((j-i)>1)
{
k=((j-i)/2);
if (strcmp(dico[k],mot)==0) return 1;
if (strcmp(dico[k],mot)>0) j=k;
else i=k;
}
if ((strcmp(dico[i],mot)==1) || (strcmp(dico[j],mot)==1)) return 1;
else return 0;
}

void purger(void)
{
int c;
while ((c=getchar()) != '\n' && c != EOF)
{}
}

Merci d'avance de votre aide ;)

4 réponses

loupius
 
mais la compilation me donne une erreur de segmentation
Non ce n'est pas la compilation qui donne cette erreur, mais l'exécution !
erreur de segmentation ===>>> problème de pointeur.
char *dico[nb_mots];
dico[nb_mots]=malloc(nb_mots*sizeof(char));
for (i=0;i<nb_mots;i++)
{
printf("Entrez le mot %i: ",i+1);
scanf("%s",dico[i]); /* Le problème se situe ici le tableau ne se remplit pas...*/
purger();
}

On voit tout de suite ce qui ne va pas:
- dico[nb_mots] est le seul élément dont l'espace mémoire est alloué et .. de plus c'est un élément qui dépasse la déclaration, c'est le 'segment fault' assuré. Sans autre commentaire.
Bonne continuation.
0
jamsss Messages postés 36 Date d'inscription   Statut Membre Dernière intervention  
 
Bon ok j'ai mis le malloc dans la boucle for:

int main()
{
char *mot;
int nb_mots,i;
mot=malloc(30*sizeof(char));

printf("Combien vous vous entrer de mots ? ");
scanf("%i",&nb_mots);
purger();
char *dico[nb_mots];
for (i=0;i<nb_mots;i++)
{
dico[i]=malloc(30*sizeof(char));
printf("Entrez le mot %i: ",i+1);
scanf("%s",dico[i]);
purger();
}
printf("Quel est le mot à comparer ? ");
scanf("%s",mot);
purger();
if (dichotomie(dico,mot,nb_mots)==1) printf("Le mot est dans le tableau\n");
else printf("Le mot n'est pas dans le tableau\n");
for (i=0;i<nb_mots;i++) free(dico[i]);
return 0;
}

ça fonctionne mais pas tout le temps...

Si je fais ça:

Combien vous vous entrer de mots ? 5
Entrez le mot 1: a
Entrez le mot 2: b
Entrez le mot 3: c
Entrez le mot 4: d
Entrez le mot 5: e
Quel est le mot à comparer ? a
Le mot est dans le tableau

Ça fonctionne parfaitement

par contre:

Combien vous vous entrer de mots ? 5
Entrez le mot 1: a
Entrez le mot 2: b
Entrez le mot 3: c
Entrez le mot 4: d
Entrez le mot 5: e
Quel est le mot à comparer ? d

le programme reste planté...

Encore un problème de mémoire ?
0
loupius
 
Je crois plutôt que dans ta fonction 'dichotomie()', il y a une boucle qui... boucle ! ;-)
Dans ce cas la solution est de rajouter une condition qui limite de nombre de tours dans la boucle et de mettre un 'printf' adéquat pour suivre ce qui se passe dans la boucle.
Evidemment, ce n'est qu'une supposition car seul toi connais le contenu de cette fonction.
Bonne continuation.
0
loupius > loupius
 
Oh s ! La fonction 'dichotomie' a été donnée... mais il faut dire qu'avec un code non indenté, on a du mal à le lire.
Amitiés.
0
loupius > loupius
 
Oui, d'ailleurs je m'étonne moi-même. D'ordinaire je ne réponds pas lorsque le code n'est pas indenté.
Bonne nuit.
0
jamsss Messages postés 36 Date d'inscription   Statut Membre Dernière intervention  
 
Non je ne pense pas, si c'était un problème de boucle dans "dichotomie" le programme ne fonctionnerait pour aucune valeur... j'ai plutôt l'impression d'un dépassement de mémoire à quelque part.
La fonction dichotomie n'as pas changée depuis mon premier message:

short dichotomie(char **dico,char *mot,short nb_mots)
{
int i,j,k;
j=nb_mots;
i=0;

while ((j-i)>1)
{
k=((j-i)/2);
if (strcmp(dico[k],mot)==0) return 1;
if (strcmp(dico[k],mot)>0) j=k;
else i=k;
}
if ((strcmp(dico[i],mot)==1) || (strcmp(dico[j],mot)==1)) return 1;
else return 0;
}

Merci
0
loupius
 
Non je ne pense pas, si c'était un problème de boucle dans "dichotomie" le programme ne fonctionnerait pour aucune valeur. Ah pourquoi ?
Dans les 2 exemples que tu as donné, il y en a un qui marche et un qui ne marche pas. Ne vois-tu pas la différence entre les deux exemples. Là c'est l'expérience qui parle: le premier exemple recherche une valeur qui est inférieure à la moyenne et l'autre qui est... supérieure.
Les test sont corrects puisque pour une dichotomie il faut tester 7 valeurs:
- inférieure à la minimum,
- la valeur minimum,
- compris entre la minimum et la valeur moyenne,
- la valeur moyenne,
- compris entre la valeur moyenne et la maximum,
- la valeur maximum,
- supérieure à la maximum.
A tester aussi avec aucun mot, avec un nombre de mots pair et avec un nombre de mots impair. Si les 21 tests sont ok, c'est que ta fonction est, à priori, correcte.
Ici ce n'est pas le cas, donc il faut rechercher ce qui cloche.
Avec l'exemple qui ne marche pas, un rapide test à la main donne:
i=0, j=5, k=0
i=2, j=5, k=2
i=1, j=5, k=1
i=2, j=5, k=2
i=1, j=5, k=1 ...
Inutile d'insister, on boucle !!! Classique !!!
Bonne réflexion.
0
jamsss Messages postés 36 Date d'inscription   Statut Membre Dernière intervention  
 
J'ai finallement fait ça:

short dichotomie(char **dico,char *mot,short nb_mots)
{
int i,j,k;
i=0;
j=nb_mots;

while ((j-i)>1)
{
k=i+((j-i)/2);
if (((j-i)%2)==0) k++;
if (strcmp(mot,dico[k-1])==0) return 1;
if (strcmp(mot,dico[k-1])<0) j=(k-1);
else i=(k-1);
}
if ((strcmp(dico[i],mot)==0) || (strcmp(dico[j],mot)==0)) return 1;
else return 0;
}

void purger(void)
{
int c;
while ((c=getchar()) != '\n' && c != EOF)
{}
}

et ça fonctionne !

Merci Loupious pour ton aide, c'est vraiment sympa de trouver des gens comme toi quand on galère, merci encore ;)

                
0