Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: minette1988 en 2 Junio 2010, 13:21 pm



Título: ordenar por nombre o deuda con la función qsort
Publicado por: minette1988 en 2 Junio 2010, 13:21 pm
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:

Código
  1. /* Programa de ejemplo de gestió de memoria dinámica. El programa tomará
  2. los registros de un fichero y reservará la memoria necesaria para poder
  3. guardarlos en memoria y ordenarlos con el qsort(), una vez ordenados los
  4. volverá a guardar en el fichero */
  5.  
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. /* macro para leer cadenas con caracteres blanco filtrando los return y
  10.    blancos iniciales  */
  11. #define lee_cad(cad,n,fin) cad[0]=getchar(); \
  12.                            while(((int)cad[0] == 10) || ((int)cad[0] == 32)) \
  13.                               cad[0]=getchar();\
  14.                            n=0; \
  15.                            while(((int)cad[n]!= 10) && (n < fin)){ \
  16.               n++; cad[n]=getchar();} \
  17.           cad[n]='\0';
  18.  
  19. struct registro{
  20.   char nombre[50];
  21.   float deuda;
  22. };
  23.  
  24. int main(){
  25.  FILE * df;
  26.  struct registro cliente;
  27.  int i,fin;
  28.  char op;
  29.  int num_registros;
  30.  struct registro *punt_memoria;
  31.  int compara();
  32.  
  33.  if((df=fopen("apuestas.dat","wb")) == NULL){
  34.     printf("\nError al crear el fichero apuestas.dat\n");
  35.     exit(1);
  36.  }
  37.  
  38.  
  39.  do{
  40.     printf("Nombre del apostante: ");
  41.     lee_cad(cliente.nombre,i,50);
  42.     //scanf("%49s",cliente.nombre);
  43.     printf("Deuda? ");
  44.     scanf("%f",&cliente.deuda);
  45.     fwrite(&cliente,sizeof(cliente),1,df);
  46.     printf("Otro(0 --> No / 1 --> Sí) ");
  47.     scanf("%d",&fin);
  48.  }
  49.  while(fin!=0);
  50.  
  51.  fclose(df);
  52.  
  53.  if((df=fopen("apuestas.dat","rb")) == NULL){
  54.     printf("\nError al abrir el fichero apuestas.dat\n");
  55.     exit(1);
  56.  }
  57.  /* Para ver cuantos registros hay en el fichero, pongo el puntero
  58.   al final, obtengo su posición y divido por el tamańo del registro */
  59.  fseek(df,0,SEEK_END);
  60.  
  61.  num_registros = ftell(df)/sizeof(cliente);
  62.  
  63.  /* Reservo la memoria necesaria para estos registros */
  64.  punt_memoria = (struct registro *)calloc(num_registros, sizeof(cliente));
  65.  
  66.  /* Leo los registro del fichero y los guardo en memoria */
  67.  
  68.  rewind(df); /* Llego el descriptor de fichero al principio */
  69.  /* Leo todos los registros y los guardo en la zona reservada de memoria */
  70.  fread(punt_memoria,sizeof(cliente),num_registros,df);
  71.  
  72.  fclose(df);
  73.  /* Ordeno el vector con qsort() */
  74.  
  75.  qsort(punt_memoria,num_registros,sizeof(cliente),compara);
  76.  
  77.  /* Guarda los registros ordenados en el fichero */
  78.  if((df=fopen("apuestas.dat","wb")) == NULL){
  79.     printf("\nError al crear el fichero apuestas.dat\n");
  80.     exit(1);
  81.  }
  82.  fwrite(punt_memoria,sizeof(cliente),num_registros,df);
  83.  fclose(df);
  84.  
  85.  /* Mostrar el contenido del fichero ordenado */
  86.  if((df=fopen("apuestas.dat","rb")) == NULL){
  87.     printf("\nError al abrir el fichero apuestas.dat\n");
  88.     exit(1);
  89.  }
  90.  fread(punt_memoria,sizeof(cliente),num_registros,df);
  91.  for(i=0; i < num_registros; i++)
  92.    printf("%s  %.1f\n",(punt_memoria+i)->nombre, (punt_memoria+i)->deuda);
  93.  fclose(df);
  94.  free(punt_memoria);
  95. } /* main() */
  96.  
  97. /* La función compara usa strcmp para ordenar alfabéticamente
  98.    el fichero */
  99.  
  100. int compara(struct registro *r1, struct registro *r2){
  101.    return(strcmp(r1->nombre, r2->nombre));
  102. }


Título: Re: ordenar por nombre o deuda con la función qsort
Publicado por: nicolas_cof en 2 Junio 2010, 13:35 pm
Código:
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.


Título: Re: ordenar por nombre o deuda con la función qsort
Publicado por: Gallu en 2 Junio 2010, 15:23 pm
Pues a simple vista diria que lo único que tienes que hacer es implementar un compara para los floats ejem.
Código
  1. int compara_deuda(struct registro *r1, struct registro *r2){
  2.    return(r1->deuda >  r2->deuda ));
  3. }
  4.  

y pasarselo al qsort donde corresponda

Código
  1. qsort(punt_memoria,num_registros,sizeof(cliente),compara_deuda);
  2.  

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

Código
  1. /* Programa de ejemplo de gestió de memoria dinámica. El programa tomará
  2. los registros de un fichero y reservará la memoria necesaria para poder
  3. guardarlos en memoria y ordenarlos con el qsort(), una vez ordenados los
  4. volverá a guardar en el fichero */
  5.  
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. /* macro para leer cadenas con caracteres blanco filtrando los return y
  10.    blancos iniciales  */
  11. #define lee_cad(cad,n,fin) cad[0]=getchar(); \
  12.                            while(((int)cad[0] == 10) || ((int)cad[0] == 32)) \
  13.                               cad[0]=getchar();\
  14.                            n=0; \
  15.                            while(((int)cad[n]!= 10) && (n < fin)){ \
  16.               n++; cad[n]=getchar();} \
  17.           cad[n]='\0';
  18.  
  19. struct registro{
  20.   char nombre[50];
  21.   float deuda;
  22. };
  23.  
  24. /* Prototipos de procedimientos */
  25. int compara_float();
  26. int compara();
  27.  
  28.  
  29. int main(){
  30.  FILE * df;
  31.  struct registro cliente;
  32.  int i,fin;
  33.  char op;
  34.  int num_registros;
  35.  struct registro *punt_memoria;
  36.  
  37.  
  38.  if((df=fopen("apuestas.dat","wb")) == NULL){
  39.     printf("\nError al crear el fichero apuestas.dat\n");
  40.     exit(1);
  41.  }
  42.  
  43.  
  44.  do{
  45.     printf("Nombre del apostante: ");
  46.     lee_cad(cliente.nombre,i,50);
  47.     //scanf("%49s",cliente.nombre);
  48.     printf("Deuda? ");
  49.     scanf("%f",&cliente.deuda);
  50.     fwrite(&cliente,sizeof(cliente),1,df);
  51.     printf("Otro(0 --> No / 1 --> Sí) ");
  52.     scanf("%d",&fin);
  53.  }
  54.  while(fin!=0);
  55.  
  56.  fclose(df);
  57.  
  58.  if((df=fopen("apuestas.dat","rb")) == NULL){
  59.     printf("\nError al abrir el fichero apuestas.dat\n");
  60.     exit(1);
  61.  }
  62.  /* Para ver cuantos registros hay en el fichero, pongo el puntero
  63.   al final, obtengo su posición y divido por el tamańo del registro */
  64.  fseek(df,0,SEEK_END);
  65.  
  66.  num_registros = ftell(df)/sizeof(cliente);
  67.  
  68.  /* Reservo la memoria necesaria para estos registros */
  69.  punt_memoria = (struct registro *)calloc(num_registros, sizeof(cliente));
  70.  
  71.  /* Leo los registro del fichero y los guardo en memoria */
  72.  
  73.  rewind(df); /* Llego el descriptor de fichero al principio */
  74.  /* Leo todos los registros y los guardo en la zona reservada de memoria */
  75.  fread(punt_memoria,sizeof(cliente),num_registros,df);
  76.  
  77.  fclose(df);
  78.  /* Ordeno el vector con qsort() */
  79.  
  80.  qsort(punt_memoria,num_registros,sizeof(cliente),compara_float);  /* simplemante cambias el parámetro con el nuevo tipo de ordenación */
  81.  
  82.  /* Guarda los registros ordenados en el fichero */
  83.  if((df=fopen("apuestas.dat","wb")) == NULL){
  84.     printf("\nError al crear el fichero apuestas.dat\n");
  85.     exit(1);
  86.  }
  87.  fwrite(punt_memoria,sizeof(cliente),num_registros,df);
  88.  fclose(df);
  89.  
  90.  /* Mostrar el contenido del fichero ordenado */
  91.  if((df=fopen("apuestas.dat","rb")) == NULL){
  92.     printf("\nError al abrir el fichero apuestas.dat\n");
  93.     exit(1);
  94.  }
  95.  fread(punt_memoria,sizeof(cliente),num_registros,df);
  96.  for(i=0; i < num_registros; i++)
  97.    printf("%s  %.1f\n",(punt_memoria+i)->nombre, (punt_memoria+i)->deuda);
  98.  fclose(df);
  99.  free(punt_memoria);
  100. } /* main() */
  101.  
  102. /* La función compara usa strcmp para ordenar alfabéticamente
  103.    el fichero */
  104.  
  105. int compara(struct registro *r1, struct registro *r2){
  106.    return(strcmp(r1->nombre, r2->nombre));
  107. }
  108. int compara_float(struct registro *r1, struct registro *r2){
  109. return(r1->deuda > r2->deuda);
  110. }
  111.