ordenar por nombre o deuda con la función qsort

Iniciado por minette1988, 2 Junio 2010, 13:21 PM

0 Miembros y 1 Visitante están viendo este tema.

minette1988

El siguiente programa ordena los nombres alfabéticamente usando qsort, lo que quiero es mediante un switch darle la opción de ordenar por el nombre u ordenar por la deuda. Lo he intentado varias veces y no me sale. Este es el código:

/* Programa de ejemplo de gestió de memoria dinámica. El programa tomará
los registros de un fichero y reservará la memoria necesaria para poder
guardarlos en memoria y ordenarlos con el qsort(), una vez ordenados los
volverá a guardar en el fichero */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* macro para leer cadenas con caracteres blanco filtrando los return y
   blancos iniciales  */
#define lee_cad(cad,n,fin) cad[0]=getchar(); \
                           while(((int)cad[0] == 10) || ((int)cad[0] == 32)) \
                              cad[0]=getchar();\
                           n=0; \
                           while(((int)cad[n]!= 10) && (n < fin)){ \
               n++; cad[n]=getchar();} \
           cad[n]='\0';

struct registro{
   char nombre[50];
   float deuda;
};

int main(){
  FILE * df;
  struct registro cliente;
  int i,fin;
  char op;
  int num_registros;
  struct registro *punt_memoria;
  int compara();

  if((df=fopen("apuestas.dat","wb")) == NULL){
     printf("\nError al crear el fichero apuestas.dat\n");
     exit(1);
  }


  do{
     printf("Nombre del apostante: ");
     lee_cad(cliente.nombre,i,50);
     //scanf("%49s",cliente.nombre);
     printf("Deuda? ");
     scanf("%f",&cliente.deuda);
     fwrite(&cliente,sizeof(cliente),1,df);
     printf("Otro(0 --> No / 1 --> Sí) ");
     scanf("%d",&fin);
  }
  while(fin!=0);

  fclose(df);

  if((df=fopen("apuestas.dat","rb")) == NULL){
     printf("\nError al abrir el fichero apuestas.dat\n");
     exit(1);
  }
  /* Para ver cuantos registros hay en el fichero, pongo el puntero
  al final, obtengo su posición y divido por el tamaño del registro */
  fseek(df,0,SEEK_END);

  num_registros = ftell(df)/sizeof(cliente);

  /* Reservo la memoria necesaria para estos registros */
  punt_memoria = (struct registro *)calloc(num_registros, sizeof(cliente));

  /* Leo los registro del fichero y los guardo en memoria */

  rewind(df); /* Llego el descriptor de fichero al principio */
  /* Leo todos los registros y los guardo en la zona reservada de memoria */
  fread(punt_memoria,sizeof(cliente),num_registros,df);

  fclose(df);
  /* Ordeno el vector con qsort() */

  qsort(punt_memoria,num_registros,sizeof(cliente),compara);

  /* Guarda los registros ordenados en el fichero */
  if((df=fopen("apuestas.dat","wb")) == NULL){
     printf("\nError al crear el fichero apuestas.dat\n");
     exit(1);
  }
  fwrite(punt_memoria,sizeof(cliente),num_registros,df);
  fclose(df);

  /* Mostrar el contenido del fichero ordenado */
  if((df=fopen("apuestas.dat","rb")) == NULL){
     printf("\nError al abrir el fichero apuestas.dat\n");
     exit(1);
  }
  fread(punt_memoria,sizeof(cliente),num_registros,df);
  for(i=0; i < num_registros; i++)
    printf("%s  %.1f\n",(punt_memoria+i)->nombre, (punt_memoria+i)->deuda);
  fclose(df);
  free(punt_memoria);
} /* main() */

/* La función compara usa strcmp para ordenar alfabéticamente
   el fichero */

int compara(struct registro *r1, struct registro *r2){
    return(strcmp(r1->nombre, r2->nombre));
}

nicolas_cof

int main() {
    ...
    int compara();
    ...


Los prototipos de las funciones se declaran fuera de la funcion main() :P

Y el macro lee_cad() no hace quedar a tu codigo muy ordenado que digamos...

Salu10.

Gallu

#2
Pues a simple vista diria que lo único que tienes que hacer es implementar un compara para los floats ejem.

int compara_deuda(struct registro *r1, struct registro *r2){
   return(r1->deuda >  r2->deuda ));
}


y pasarselo al qsort donde corresponda


qsort(punt_memoria,num_registros,sizeof(cliente),compara_deuda);


ya me diras si te funciona ...
Lo siguiente ordena por deuda de manera ascendente


/* Programa de ejemplo de gestió de memoria dinámica. El programa tomará
los registros de un fichero y reservará la memoria necesaria para poder
guardarlos en memoria y ordenarlos con el qsort(), una vez ordenados los
volverá a guardar en el fichero */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* macro para leer cadenas con caracteres blanco filtrando los return y
   blancos iniciales  */
#define lee_cad(cad,n,fin) cad[0]=getchar(); \
                           while(((int)cad[0] == 10) || ((int)cad[0] == 32)) \
                              cad[0]=getchar();\
                           n=0; \
                           while(((int)cad[n]!= 10) && (n < fin)){ \
               n++; cad[n]=getchar();} \
           cad[n]='\0';

struct registro{
   char nombre[50];
   float deuda;
};

/* Prototipos de procedimientos */
int compara_float();
int compara();


int main(){
  FILE * df;
  struct registro cliente;
  int i,fin;
  char op;
  int num_registros;
  struct registro *punt_memoria;


  if((df=fopen("apuestas.dat","wb")) == NULL){
     printf("\nError al crear el fichero apuestas.dat\n");
     exit(1);
  }


  do{
     printf("Nombre del apostante: ");
     lee_cad(cliente.nombre,i,50);
     //scanf("%49s",cliente.nombre);
     printf("Deuda? ");
     scanf("%f",&cliente.deuda);
     fwrite(&cliente,sizeof(cliente),1,df);
     printf("Otro(0 --> No / 1 --> Sí) ");
     scanf("%d",&fin);
  }
  while(fin!=0);

  fclose(df);

  if((df=fopen("apuestas.dat","rb")) == NULL){
     printf("\nError al abrir el fichero apuestas.dat\n");
     exit(1);
  }
  /* Para ver cuantos registros hay en el fichero, pongo el puntero
  al final, obtengo su posición y divido por el tamaño del registro */
  fseek(df,0,SEEK_END);

  num_registros = ftell(df)/sizeof(cliente);

  /* Reservo la memoria necesaria para estos registros */
  punt_memoria = (struct registro *)calloc(num_registros, sizeof(cliente));

  /* Leo los registro del fichero y los guardo en memoria */

  rewind(df); /* Llego el descriptor de fichero al principio */
  /* Leo todos los registros y los guardo en la zona reservada de memoria */
  fread(punt_memoria,sizeof(cliente),num_registros,df);

  fclose(df);
  /* Ordeno el vector con qsort() */

  qsort(punt_memoria,num_registros,sizeof(cliente),compara_float);  /* simplemante cambias el parámetro con el nuevo tipo de ordenación */

  /* Guarda los registros ordenados en el fichero */
  if((df=fopen("apuestas.dat","wb")) == NULL){
     printf("\nError al crear el fichero apuestas.dat\n");
     exit(1);
  }
  fwrite(punt_memoria,sizeof(cliente),num_registros,df);
  fclose(df);

  /* Mostrar el contenido del fichero ordenado */
  if((df=fopen("apuestas.dat","rb")) == NULL){
     printf("\nError al abrir el fichero apuestas.dat\n");
     exit(1);
  }
  fread(punt_memoria,sizeof(cliente),num_registros,df);
  for(i=0; i < num_registros; i++)
    printf("%s  %.1f\n",(punt_memoria+i)->nombre, (punt_memoria+i)->deuda);
  fclose(df);
  free(punt_memoria);
} /* main() */

/* La función compara usa strcmp para ordenar alfabéticamente
   el fichero */

int compara(struct registro *r1, struct registro *r2){
    return(strcmp(r1->nombre, r2->nombre));
}
int compara_float(struct registro *r1, struct registro *r2){
return(r1->deuda > r2->deuda);
}

Nadie alcanza la meta con un solo intento, ni perfecciona la vida con una sola rectificación, ni alcanza altura con un solo vuelo.