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));
}
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.
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);
}