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 :

comment inserer un élément dans un tableau trié ? [Débutant(e)]


Sujet :

C

  1. #1
    Membre régulier
    Inscrit en
    Novembre 2007
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 8
    Par défaut comment inserer un élément dans un tableau trié ?
    Bonjour,

    Je viens vous demander votre aide à propos d'un problème que je n'arrive pas à surmonter, malgré que j'ai lu les cours, la FAQ et les tuto de developpez.com et de mon IUT.

    En fait, le projet traite d'un répertoire téléphonique où on a différentes fonctions et où les contacts sont triés par ordre alphabétique sur le nom dans un tableau de 100 postes. J'ai tout fait en commencant par le plus facile et je bloque maintenant sur la dernière fonction qui me permet d'ajouter par ordre alphabétique sur le nom un contact saisi.

    Le problème est que j'ai testé plusieurs algo et au pire des cas, j'ai une erreur de segmentation, au meilleurs des cas, après un certains nombre de contacts, le tableau n'est plus trié du tout :-/

    Je suis sûr que le truc est tout bête, mais je bloque dessus depuis plusieurs jours, je ne sais plus quoi faire, j'ai tenté bcp de choses et c'est pour ça que je poste ici...

    Voici le code de la dernière version de ma fonction pour inscrire un contact, que j'ai reprise de mon cours en TD :
    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
    int inscrire_contact(
    					  Contact (*tableau)[100], int (*pros)[100], int *NUMC, int *NUMP,
     
    					  CH15 nom, CH15 prenom, CH10 numero, char ctgrie
     
    					  )
    {
     
    	int i, indice;
     
     
     
    	for(i = (*NUMC)-1; i >= 0 && strcmp(nom, tableau[i]->nom) < 0; i--)
     
    	{
     
    		(*tableau)[i] = (*tableau)[i-1];
     
    	}
     
    	(*NUMC)++;
    	i++;
     
    	indice = i;
     
    	printf("\n\t%d\n", i);
     
    	strcpy((*tableau)[indice].nom, nom);
     
    	strcpy((*tableau)[indice].prenom, prenom);
     
    	strcpy((*tableau)[indice].numero, numero);
     
    	(*tableau)[indice].ctgrie = ctgrie;
     
     
    	//AJOUT DANS PROS si ctgrie == 'P'
     
    	//...
     
     
    	return indice;
     
    }
    Voila, à l'aide s'il vous plaît. Je peux répondre à toutes les questions que vous aurez étant donné que je connais mon programme sur le bout des doigts... Je pourrai vous passer le code que vous voudrez. Merci encore !

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    104
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 104
    Par défaut
    Je regarde ton problème et j'essaie de te répondre...

    Pourrais tu donner les significations de tes paramètres.

  3. #3
    Membre chevronné Avatar de Pierre Maurette
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    283
    Détails du profil
    Informations personnelles :
    Âge : 69
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 283
    Par défaut
    Bonjour,

    Je n'ai pas tout compris de vos structures de données. Je vous suggère malgré tout de bien valider votre travail sans trier. C'est à dire par exemple d'ajouter à la fin, mais en étant certain d'avoir bien la mémoire pour le faire.
    Ensuite vous écrirez le tri, en vous inspirant si vous le souhaitez de ça:
    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    typedef struct  {
    	char* nom;
    	int numero;
    } repert;
     
    void printrepert(repert* tab, int taille){
    	int i;
    	for(i = 0; i < taille; i++){
    		printf("%d - %s  %d\n", i, tab[i].nom, tab[i].numero);
    	}
    }
     
    int comparenom(const void* a, const void* b){
    	return strcmp(((repert*)a)->nom, ((repert*)b)->nom);
    }
     
    int comparecasenom(const void* a, const void* b){
    	return strcasecmp(((repert*)a)->nom, ((repert*)b)->nom);
    }
     
    int main(void) {
    #define PETRUS_TAILLE (sizeof rep / sizeof(repert))
    	repert rep[] = {{"pierre", 100}, {"andré", 100}, {"Jules", 100}, {"thomas", 100}};
    	printrepert(rep, PETRUS_TAILLE);
    	qsort(rep, PETRUS_TAILLE, sizeof(repert), comparenom);
    	printrepert(rep, PETRUS_TAILLE);
    	qsort(rep, PETRUS_TAILLE, sizeof(repert), comparecasenom);
    	printrepert(rep, PETRUS_TAILLE);	
    #undef PETRUS_TAILLE
    	return EXIT_SUCCESS;
    }
    Vous constaterz un problème avec strcmp() et les majuscules. Vous aurez alors au moins trois solutions:
    - Utiliser si vous y avez droit (pas ANSI) strcasecmp().
    - Formatter à l'origine les noms, ce qui ne peut pas faire de mal. Tout majuscules, tout minuscules, majuscule initiale.
    - Ecrire votre fonction compare()
    et même une quatrième:
    - Taper ce qui va bien dans Google, à base de qsort(), majuscule, minuscule, uppercas, lowecase, etc.

    Bon courage...

    Pierre

  4. #4
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Pierre Maurette :
    Vous constaterz un problème avec strcmp() et les majuscules. Vous aurez alors au moins trois solutions:
    - Utiliser si vous y avez droit (pas ANSI) strcasecmp().
    stricmp est ANSI et fait une comparaison insensible à la casse

  5. #5
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    2 questions pour commencer :
    • ton tableau (*tableau) peut-il contenir un élément de plus ?? (c'est à dire as-tu déjà fait de la réllalocation, ou pouvait-il dès le départ contenir N+1 éléments) ??

    • tes champs sont-ils alloués ou pré-dimensionnés (pour les strcpy) ??

  6. #6
    Membre chevronné Avatar de Pierre Maurette
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    283
    Détails du profil
    Informations personnelles :
    Âge : 69
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 283
    Par défaut
    Citation Envoyé par diogene Voir le message
    Pierre Maurette :
    stricmp est ANSI et fait une comparaison insensible à la casse
    Elle n'est pas dans mon texte de la norme, et elle est POSIX d'après Google...

  7. #7
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par diogene Voir le message
    stricmp est ANSI et fait une comparaison insensible à la casse
    Euh, non. C'est pas ANSI-C du tout...

    http://delahaye.emmanuel.free.fr/images/stricmp.png

  8. #8
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Emmanuel Delahaye :
    Euh, non. C'est pas ANSI-C du tout...
    Pierre Maurette :
    elle est POSIX d'après Google...
    Oui, mes sources étaient incorrectes.

  9. #9
    Membre régulier
    Inscrit en
    Novembre 2007
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 8
    Par défaut
    Salut,

    Pardon d'avoir mis autant de temps à répondre. Concernant la structure de mes données, pour le tableau et les chaines de caractère le code suivant vaudra mieux qu'un long discours :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    typedef char CH15[16];
    typedef char CH10[11];
     
    typedef struct
    {
    	CH15	nom;
    	CH15	prenom;
    	CH10	numero;
    	char	ctgrie;
    } Contact;
    "tableau" est un tableau de contacts de 100 postes que j'ai initialisé dans le main() comme suit : "NUMC" est une int qui contient le nombre de contacts dans ce tableau, qui vaut donc 0 au début : nom, prenom, ctgrie, et numero sont des variables qui contiennent des données entrées par l'utilisateur dans la fonction qui appelle celle ci.

    "pros" et "NUMP" son respectivement un autre tableau d'indice des contacts professionels et un nombre de contacts dans ce tableau d'indice sur lequel je ne veux pas travailler tout de suite avant d'avoir résolu ce soucis.

    Concernant le strcpy, c'est tout ce que je peux utiliser, on a même pas encore vu les malloc et autres joyeuseté du même genre, et encore moins le droit de les utiliser.

    A noter aussi que je n'ai pas le droit d'utiliser qsort. Au début, j'avais terminé le projet en utilisant cette fonction qui me permet de trier le tableau facilement. Ensuite mes professeurs mon cassé dans mon élan en m'informant que je ne pouvais pas et qu'il fallait que j'utilise le cours pour faire un tri par insertion à ma sauce. Le problème est que j'ai recopié le cours, ca devrait fonctionner, mais que ca nemarche pas...

    Autre précision: si je veux ajouter mes données à la fin du tableau, sans tri, ca fonctionne parfaitement. Mais dès que j'ajoute ce tri, j'arrive plus à comprendre pourquoi à un moment j'ai une segfault, et à d'autre moments, le tableau n'est tout simplement pas trié :-/

    J'ai tout essayé, est ce un problème de parenthèses quelques part ou une étoile mal placée ? Je ne pense pas :-/

    Merci encore !

  10. #10
    Membre régulier
    Inscrit en
    Novembre 2007
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 8
    Par défaut
    Salut,

    aussi bizarre que cela puisse paraître j'ai eu hier soir vers une heure du matin une illumination, un miracle. Je me suis dit : "voila, dans le strcpy, pourquoi est ce que je n'utilise pas l'opérateur "->" ? parce que ca ne voulait pas fonctionner et parce que je n'avais pas de temps à perdre pour essayer de comprendre pourquoi. Mais alors, pourquoi est ce que je l'utilise dans ma boucle for ?"

    J'ai donc remplacé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for(i = (*NUMC)-1; i >= 0 && strcmp(nom, tableau[i]->nom) < 0; i--)
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for(i = (*NUMC)-1; i >= 0 && strcmp(nom, (*tableau)[i].nom) < 0; i--)
    et là, miracle, je n'ai plus aucun problème, le tri par insertion se fait parfaitement. Je n'ai plus de segfault, ni d'erreurs de tri. J'ai même pu en ajouter un peu pour avoir un tri et sur le nom, et sur le prénom avec ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for(i = (*NUMC)-1; (i >= 0) && ( (strcmp(nom, (*tableau)[i].nom) < 0) || ( (!strcmp(nom, (*tableau)[i].nom)) && (strcmp(prenom, (*tableau)[i].prenom) < 0)) ); i--)
    Quand je pense qu'avant hier, j'ai harcelé une prof. d'algo pour qu'elle trouve le bug avec moi et qu'après une heure et demi de travail, on n'avait toujours rien repéré...

    Conclusion : Ca fonctionne, je ne sais pas pourquoi, mais mon projet est à rendre entièrement terminé pour demain matin, je n'ai donc pas le temps de me casser la tête dessus tout de suite mais je le ferai après être passé devant mon jury. Merci à tous pour votre aide.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 6
    Dernier message: 11/05/2014, 10h29
  2. Réponses: 6
    Dernier message: 26/11/2007, 16h26
  3. Réponses: 2
    Dernier message: 16/05/2006, 11h53
  4. inserer un élément dans un tableau
    Par caesa dans le forum Oracle
    Réponses: 1
    Dernier message: 20/03/2006, 17h03

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