Algo de tri en c pour traitement des fichier

Fermé
limbergh Messages postés 658 Date d'inscription dimanche 8 juillet 2007 Statut Membre Dernière intervention 29 juin 2010 - 2 mars 2008 à 13:09
 AlHassan - 1 févr. 2011 à 02:31
Bonjour,
j'ai vu au cours (du soir) le traitement des fichiers ainsi que comment définir une structure...
J'ai commencé un code qui demande à l'utilisateur d'encoder nom,prénom, age et taille
de plusieurs personnes...
j'aimerais bien trier ce que j'encode dans le fichier et je ne sais pas comment faire pour
trier par ordre alphabétique... Je sais pour un tableau avec des nombres mais pas pour des
lettres...

Voici mon code

#include <stdio.h>

#include <stdlib.h>
#define taillemax 30

typedef struct personne
{
char nom[taillemax];
char prenom[taillemax];
int age;
int taille;
}pers;

int main(int argc, char *argv[])
{

pers p, tableau[5];
char nom2[taillemax];
char prenom2[taillemax];
int i=0, nbpers;
FILE *fichier;
char nomfichier[taillemax];

do
{
printf("\n nom? ");
gets(nom2);
printf("\n prenom? ");
gets(prenom2);
if (strlen(nom2) > 0)
{
strcpy(p.nom, nom2);
strcpy(p.prenom, prenom2);
printf("\n age : ");
scanf("%d", &p.age);
printf("\n taille en cm : ", &p.taille);
scanf("%d", &p.taille);
printf("\n vous avez encodez : %s\t%s\t%d\t%d", p.nom, p.prenom, p.age, p.taille);
fflush(stdin);
tableau[i++]=p;
}

}
while((strlen(nom2)>0)&&(i<5));

nbpers=i;
for (i=0; i<nbpers; i++)
printf("\n ENCODAGE : %s\t%s\t%d\t%d", tableau[i].nom, tableau[i].prenom, tableau[i].age, tableau[i].taille);

printf("\n Encodez le nom du fichier :");
gets(nomfichier);

fichier=fopen(nomfichier,"w");
for (i=0; i<nbpers; i++)
fprintf(fichier, "\n %s\t%s\t%d\t%d", tableau[i].nom, tableau[i].prenom, tableau[i].age, tableau[i].taille);
fclose(fichier);


system("PAUSE");
return 0;
}


Merci d'avance
A voir également:

9 réponses

mamiemando Messages postés 33268 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 18 septembre 2024 7 780
2 mars 2008 à 14:13
En fait c'est le même principe qu'avec des chiffres, sauf qu'il faut utiliser une relation d'ordre (en l'occurrence strcmp vu ce que tu veux faire).

Exemple :
https://www.thinkage.ca/gcos/expl/c/lib/qsort.html

Bonne chance
0
limbergh Messages postés 658 Date d'inscription dimanche 8 juillet 2007 Statut Membre Dernière intervention 29 juin 2010 140
2 mars 2008 à 19:47
salut,
voilà j'ai penché sur mon problème, mais ça ne tourne pas. si quelqu'un voit mon
erreur, si il peut me l'expliquer, c'est avec plaisir...

Mon code :

#include <stdio.h>

#include <stdlib.h>
#define taillemax 30

typedef struct personne
{
char nom[taillemax];
char prenom[taillemax];
int age;
int taille;
}pers;
int sw=0;
int main(int argc, char *argv[])
{

pers p, tableau[5];
char nom2[taillemax];
char prenom2[taillemax];
int i=0, nbpers;
FILE *fichier;
char nomfichier[taillemax];

do
{
printf("\n nom : ");
gets(nom2);
printf("\n prenom : ");
gets(prenom2);
if (strlen(nom2) > 0)
{
strcpy(p.nom, nom2);
strcpy(p.prenom, prenom2);
printf("\n age : ");
scanf("%d", &p.age);
printf("\n taille en cm : ", &p.taille);
scanf("%d", &p.taille);
printf("\n vous avez encodez : %s\t%s\t%d\t%d", p.nom, p.prenom, p.age, p.taille);
fflush(stdin);
tableau[i++]=p;
}

}
while((strlen(nom2)>0)&&(i<5));

nbpers=i;
for (i=0; i<nbpers; i++)
printf("\n ENCODAGE : %s\t%s\t%d\t%d", tableau[i].nom, tableau[i].prenom, tableau[i].age, tableau[i].taille);

printf("\n Encodez le nom du fichier :");
gets(nomfichier);

fichier=fopen(nomfichier,"w");
for (i=0; i<nbpers; i++)
fprintf(fichier, "\n %s\t%s\t%d\t%d", tableau[i].nom, tableau[i].prenom, tableau[i].age, tableau[i].taille);
fclose(fichier);

//jusque içi tout va bien

do
{
char x[taillemax];
for (i=0;i<5;i++)

if(strcmp(tableau[i].nom,tableau[i+1].nom)>0)
{
strcpy(x,tableau[i].nom);
strcpy(tableau[i].nom,tableau[i+1].nom);
strcpy(tableau[i+1].nom,x);
sw=1;
}
}
while (sw==1);


for (i=0; i<nbpers; i++)
printf("\n TRI : %s\t%s\t%d\t%d", tableau[i].nom, tableau[i].prenom, tableau[i].age, tableau[i].taille);

system("PAUSE");
return 0;
}


Merci
0
printf("\n taille en cm : ", &p.taille);// je crois k c'est une petite erreur a éviter car en ce moment //vous n'avez pas encore receuilli la taille.....
//vous devriez faire donc printf("\n taille en cm : "); simplement !
if(strcmp(tableau[i].nom,tableau[i+1].nom)>0) // ensuite je vous conseillerai d'utiliser l'egalité //avec strcmp pour dire k les 2 sont identiques et la difference(!=) pour dire le contraire et non(>)
J'ose esperer vous etre utile !Bonne chance !
0
limbergh Messages postés 658 Date d'inscription dimanche 8 juillet 2007 Statut Membre Dernière intervention 29 juin 2010 140
2 mars 2008 à 21:01
Bonsoir tout le monde, en forme?

j'ai vu au cours (du soir) et sur ce même site le traitement des fichiers...
J'ai fait un code qui demande à l'utilisateur d'introduire une suite de réponses aux questions posées et ensuite d'enregistrer le tout dans un fichier.
Jusque la pas de problème, mais j'aimerais pouvoir trier par ordre les noms de personnes introduites et c'est la que mon code ne fonctionne pas???

Si quelqu'un peut m'expliquer mon ou mes erreurs, c'est avec plaisir ...

Voici mon code :


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define taillemax 30
 
typedef struct personne  
{
char nom[taillemax];
char prenom[taillemax];
int age;
int taille;
}pers;
int sw=0;
 
int main(int argc, char *argv[])
{
 
pers p, tableau[5];
char nom2[taillemax];
char prenom2[taillemax];
int i=0, nbpers;
FILE *fichier;
char nomfichier[taillemax];
 
do
{
printf("\n nom : ");
gets(nom2);
printf("\n prenom : ");
gets(prenom2);
if (strlen(nom2) > 0)
{
                 strcpy(p.nom, nom2);
                 strcpy(p.prenom, prenom2);
                 printf("\n age :  ");
                 scanf("%d", &p.age);
                 printf("\n taille en cm : ", &p.taille);
                 scanf("%d", &p.taille);
                 printf("\n vous avez encodez : %s\t%s\t%d\t%d", p.nom, p.prenom, p.age, p.taille);
                 fflush(stdin);
                 tableau[i++]=p;
}
                     
}
while((strlen(nom2)>0)&&(i<5));  
 
nbpers=i;
for (i=0; i<nbpers; i++)
printf("\n ENCODAGE : %s\t%s\t%d\t%d", tableau[i].nom, tableau[i].prenom, tableau[i].age, tableau[i].taille);
 
printf("\n Encodez le nom du fichier :");
gets(nomfichier);
 
fichier=fopen(nomfichier,"w");
for (i=0; i<nbpers; i++)
fprintf(fichier, "\n  %s\t%s\t%d\t%d", tableau[i].nom, tableau[i].prenom, tableau[i].age, tableau[i].taille);
fclose(fichier);
 
//jusque içi tout va bien
 
do
{
char x[taillemax];
 
for (i=0;i<=nbpers-1;i++)
 
if(strcmp(tableau[i].nom,tableau[i+1].nom)>0)
{
      strcpy(x,tableau[i].nom);
      strcpy(tableau[i].nom,tableau[i+1].nom);
      strcpy(tableau[i+1].nom,x);
      sw=1;
}
}
while (sw==1);
 
 
for (i=0; i<nbpers; i++)
printf("\n TRI : %s\t%s\t%d\t%d", tableau[i].nom, tableau[i].prenom, tableau[i].age, tableau[i].taille);
 
  system("PAUSE");     
  return 0;
}


Merci d'avance


Limbergh
0
mamiemando Messages postés 33268 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 18 septembre 2024 7 780
2 mars 2008 à 21:26
Ah les joies du C c'est tellement plus simple en C++ ;-)
Voici un code pour que tu vois comment faire :
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#define TAILLE_MAX 30 // par convention les constantes en capitales

typedef struct personne{
    char nom[TAILLE_MAX];
    char prenom[TAILLE_MAX];
    unsigned age; // unsigned plutot que int puisque c'est positif
    unsigned taille;
}pers;

struct personne creer_pers(
    const char *nom0,const char *prenom0,
    unsigned age0,unsigned taille0
){
    struct personne p;
    // on vérifie que la chaine prenom / nom tient dans la structure.
    // idéalement ces deux chaînes devraient être allouées dynamiquement avec un malloc
    if(strlen(nom0) > TAILLE_MAX) return p;
    if(strlen(prenom0) > TAILLE_MAX) return p;
    strcpy(p.nom,nom0);
    strcpy(p.prenom,prenom0);
    p.age = age0;
    p.taille = taille0;
    return p;
}

int compare_pers(const struct personne *p1,const struct personne *p2){
    // 1) je compare sur le nom
    if(strcmp(p1->nom,p2->nom) < 0) return -1;
    if(strcmp(p1->nom,p2->nom) > 0) return 1;

    // 2) si je suis pas arrivé à distinguer je compare le prénom
    if(strcmp(p1->prenom,p2->prenom) < 0) return -1;
    if(strcmp(p1->prenom,p2->prenom) > 0) return 1;

    // 3) si je suis pas arrivé à distinguer je compare l'age
    if(p1->age < p2->age) return -1;
    if(p1->age > p2->age) return 1;

    // si une personne est identifiée sur son nom prenom (pas d'homonyme) alors
    // on s'arrête là et on retourne 0. Sinon on continue à comparer

    // 4) si je suis pas arrivé à distinguer je compare la taille
    if(p1->taille < p2->taille) return -1;
    if(p1->taille > p2->taille) return 1;

    // 5) mmmh en fait si je suis pas arrivé à distinguer c'est que c'est la
    // même personne :-)
    return 0;
}

void print_pers(const struct personne *p){
    printf(
        "nom = %s, prenom = %s, age = %i, taille = %i\n",
        p->nom,p->prenom,p->age,p->taille
    );
}

int main(){
    unsigned i,nb = 5;
    pers *gens = (pers *)malloc(nb*sizeof(pers));
    gens[0] = creer_pers("bon" ,"jean",33,195);
    gens[1] = creer_pers("afeu","pierre",36,175);
    gens[2] = creer_pers("afeu","pierre",27,168);
    gens[3] = creer_pers("bon" ,"jean",34,175);
    gens[4] = creer_pers("abel","mira",25,175);

    printf("avant tri: ****************\n");
    for(i=0;i<nb;++i) print_pers(&gens[i]);
    qsort(gens,nb,sizeof(pers),compare_pers);

    printf("apres tri: ****************\n");
    for(i=0;i<nb;++i) print_pers(&gens[i]);

    free(gens);
    return 0;
}

Ce qui donne :
avant tri: ****************
nom = bon, prenom = jean, age = 33, taille = 195
nom = afeu, prenom = pierre, age = 36, taille = 175
nom = afeu, prenom = pierre, age = 27, taille = 168
nom = bon, prenom = jean, age = 34, taille = 175
nom = abel, prenom = mira, age = 25, taille = 175
apres tri: ****************
nom = abel, prenom = mira, age = 25, taille = 175
nom = afeu, prenom = pierre, age = 27, taille = 168
nom = afeu, prenom = pierre, age = 36, taille = 175
nom = bon, prenom = jean, age = 33, taille = 195
nom = bon, prenom = jean, age = 34, taille = 175

Bonne chance
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
limbergh Messages postés 658 Date d'inscription dimanche 8 juillet 2007 Statut Membre Dernière intervention 29 juin 2010 140
2 mars 2008 à 21:40
Salut,
j'ai pas tout compris mais je vais regarder ça à mon aise, il y a des choses que je n'ai pas encore vu
au cours...
Mais tu sais m'expliquer pourquoi ça ne fonctionne pas mon algo de tri!!!

Merci d'avance pour tes explications...
0
scipiones Messages postés 19 Date d'inscription vendredi 29 février 2008 Statut Membre Dernière intervention 11 mars 2008 3
2 mars 2008 à 21:42
Tiens c'est marrant, on a le même genre d'exo...


Alors comme j'ai pas envie de revenir sur ce code xD


Je te copie colle le progz qui ressemble fortement au tiens ;) Ne fais pas attention au tri par prénom, c'était simplement pour faire des tests ^^"

Voici le ptit code pour le tri que tu retrouves à la fin du progz, une double boucle, et le tour est joué =) :

void tri()
{
struct etudiant eleve;
int i,k;
struct etudiant temp;
for (i = 0; i< nbeleves-1; i++)
{
eleve=tableau[i];
for(k=i+1;k<nbeleves;k++)
{
if(strcmp(eleve.nom,tableau[k].nom)>0)
{
temp=eleve;
eleve=tableau[k];
tableau[k]=temp;
}
}
tableau[i] = eleve;
}
}


-----------------------------------------------------------------------------------------------------------

#include<stdio.h>
#include<string.h>
#include<ctype.h>
void saisie();
void affichage();
void sauvegarde();
void chargement();
void conv_maj();
void tri_prenom();
int recherche(char nomrech[]);
void tri();

struct etudiant {

char nom[20];
char prenom[20];
int age;
};

struct etudiant tableau[100];
int nb = 0;
int nbeleves = 0;


main()
{
float resultat;
struct etudiant eleve;
char nom [20];
int numcase;
int choix = 1;

while (choix != 0)
{
printf("-1- saisie\n");
printf("-2- affichage\n");
printf("-3- recherche d'un nom\n");
printf("-4- sauvegarde\n");
printf("-5- chargement\n");
printf("-6- tri\n");
printf("-7- tri par prenom\n");
printf("-0- quitter\n");
printf("choix : ");
scanf("%d",&choix);

switch(choix)
{
case 1: saisie();
break;
case 2: affichage();
break;
case 3: printf("Nom:");
scanf("%s",nom);
numcase = recherche(nom);
if (numcase == -1)
{
printf("%s non trouve\n",nom);
}
else
{
eleve = tableau[numcase];
printf("%s\n",eleve.nom);
printf("%s\n",eleve.prenom);
printf("%d\n",eleve.age);
}
break;
case 4: sauvegarde();
break;
case 5: chargement();
break;
case 6: tri();

break;
case 7: tri_prenom();
break;
case 0: printf("Au revoir\n");
break;
default: printf("choix non valide\n");
break;
}
}
}

/*---------------------------------------------------------*/

void saisie()
{
struct etudiant eleve;
int i;
i = nbeleves;

while(strcmp (eleve.nom,"fin") != 0)
{
printf("Nom (fin pour terminer): ");
scanf("%s", eleve.nom);
if (strcmp (eleve.nom,"fin") != 0)
{
printf("Prenom: ");
scanf("%s" ,eleve.prenom);
printf("Age: ");
scanf("%d",&eleve.age);
tableau[i++] = eleve;
}
}
nbeleves = i;
conv_maj();
}


/*--------------------------------------------------------*/

void affichage()
{
int i;
struct etudiant eleve;
for (i=0; i < nbeleves; i++)
{
eleve = tableau[i];
printf("%s %s %d\n",eleve.nom, eleve.prenom, eleve.age);
}
printf("\n");
}

/*--------------------------------------------------------*/

void conv_maj()
{
int i, j, longueur;
struct etudiant eleve;
for (i=0; i < nbeleves; i++)
{
eleve = tableau[i]; /*on fait les modifs ds eleve et non ds le tableau*/
longueur = strlen(eleve.nom);
for (j = 0; j < longueur; j++)
{
eleve.nom[j] = toupper(eleve.nom[j]);
}
tableau[i] = eleve; /* permet de remettre la modif ds le tableau*/
}
printf("\n");
}

/*--------------------------------------------------------*/

int recherche(char nomrech[])
{
struct etudiant eleve;
int i, numero = -1;
for (i=0; i < nbeleves; i++)
{
eleve = tableau[i];
if (strcmp (eleve.nom,nomrech) == 0 )
{
numero = i;
}
}
return numero;
}

/*--------------------------------------------------------*/

void sauvegarde()
{
int i;
struct etudiant eleve;
FILE *f1;
f1 = fopen("liste_etudiant.txt","w");
for (i=0; i < nbeleves; i++)
{
eleve = tableau[i];
fprintf(f1,"%s %s %d\n",eleve.nom, eleve.prenom, eleve.age);
}
fclose(f1);
printf("sauvegarde");
}

/*--------------------------------------------------------*/

void chargement()
{
int i, retour;
struct etudiant eleve;
FILE *f1;
i = 0;
f1 = fopen("liste_etudiant.txt","r");
while (!feof(f1))
{
retour = fscanf(f1,"%s %s %d\n",eleve.nom, eleve.prenom, &eleve.age);
if (retour != EOF)
tableau[i++] = eleve;
}
nbeleves = i;
fclose(f1);
printf("charge");
}

/*---------------------------------------------------------*/

void tri()
{
struct etudiant eleve;
int i,k;
struct etudiant temp;
for (i = 0; i< nbeleves-1; i++)
{
eleve=tableau[i];
for(k=i+1;k<nbeleves;k++)
{
if(strcmp(eleve.nom,tableau[k].nom)>0)
{
temp=eleve;
eleve=tableau[k];
tableau[k]=temp;
}
}
tableau[i] = eleve;
}
}

/*--------------------------------------------------------*/

void tri_prenom()
{
struct etudiant eleve;
int i,k;
struct etudiant temp;
for (i = 0; i< nbeleves-1; i++)
{
eleve=tableau[i];
for(k=i+1;k<nbeleves;k++)
{
if(strcmp(eleve.prenom,tableau[k].prenom)>0)
{
temp=eleve;
eleve=tableau[k];
tableau[k]=temp;
}
}
tableau[i] = eleve;
}
}
0
limbergh Messages postés 658 Date d'inscription dimanche 8 juillet 2007 Statut Membre Dernière intervention 29 juin 2010 140
2 mars 2008 à 22:09
Salut scipiones,
effectivement on a plus ou moins les même exo mais je ne maitrise pas
du tout les ' struct', c'est l'horreur...

Merci pour tes explications et ton copier/coller...
0
scipiones Messages postés 19 Date d'inscription vendredi 29 février 2008 Statut Membre Dernière intervention 11 mars 2008 3
2 mars 2008 à 22:16
Pourtant c'est pas ce qu'il y a de plus compliqué =)


D'après ce que j'ai vu tu les as tout de même abordé ^^

Alors là pour le tri, c'est simple, on prend une structure temporaire qui nous serre simplement à faire la vase communiquant pour ranger les enregistrements dans le bon ordre.


Mais on compare pas tout l'enregistrement, juste le champ nom, du coup c'est eleve.nom qu'on compare avec le eleve.nom suivant (c'est pour ca que les deux boucles sont décalées, l'une commence à 0 et l'autre à 1 ;))

Si je peux te conseiller ce lien pour l'algo de tri :

http://pise.info/algo/techniques.htm


Là tu trouveras l'algo de tri tout fait, y a plus qu'à comme on dit :p


Si tu as des questions, je suis comme toi, j'apprends en ce moment, j'ai mon partiel ce mardi ^^' Mais si jpeux t'éclairer ;)
0
limbergh Messages postés 658 Date d'inscription dimanche 8 juillet 2007 Statut Membre Dernière intervention 29 juin 2010 140
2 mars 2008 à 22:52
merci pour tout scipiones....
Si j'ai encore des problèmes je te contacterai si jamais tu sais m'aider...
0