No ordena alfabeticamente

Dudas sobre el C/C++ en general
Responder
Mensaje
Autor
jfenix96
Mensajes: 3
Registrado: 30/07/2018 9:48 am

No ordena alfabeticamente

#1 Mensaje por jfenix96 » 05/08/2018 2:48 pm

Hola a todos, no necesito que hagan mi tarea y eso, tengo un problema con mi codigo porque en donde esta el system pause carga mal el vector de estructura del archivo de texto y no se porque por ej:
Apellido[0]=1
Apellido[1]=2
Apellido[2]=3

al cargar la estructura me sale
Apellido[0]=1
Apellido[1]=2
Apellido[2]=
Apellido[3]=3

siempre en la ultima linea del archivo de texto

Código: Seleccionar todo

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

typedef struct 
{
	int Pparcial;
	int Sparcial;
	int Tparcial;
	int Cparcial;
	float promedio;
}notas;

typedef struct
{
	char nombre[50];
	char apellido[50];
	notas notalumno;
}alumnos;


int cargaralumno(char nombre[],int i);
char menu2();
void mostrarA(char nombre[],int i);
void ordenar_nombre(int n,char nombre[]);
int callback(const void *alumno_1, const void *alumno_2);

int main (int argc, char *argv[])
{
	char op;
	int i=1;
	
	char nombre[]="estudiantes.txt";
	FILE *p;
	
	p = fopen (nombre, "r+");
	if (p == NULL){
		printf("\nEl archivo no existe, se creara con el nombre: %s.\n", nombre);
		p = fopen( nombre, "w+"); 
		if (p == NULL){
			printf("\nERROR: El archivo no se pudo crear ");
			exit(1);
		}
	}
	fclose(p);
	
	
	
do{	
	/*	system("clear");		*/
	op=menu2(i);				/*menú retorna la opción elegida*/
/*	system("clear");		*/
		
	switch(op){
		case '1': i=cargaralumno(nombre,i);			/**/
		break;
		case '3': mostrarA(nombre,i);			/**/
		break;
		case '2': ordenar_nombre(i,nombre);			/**/
		break;
		case '4': printf ("El archivo donde se guardaron los datos se llama: '%s'.\n", nombre);			/**/
		break;
		case '9': printf("Fin del programa... ");
		break;
		default: printf("\n Opcion NO valida!");
	break;
	}
}while(op!=9);
	
	
	
return 0;
}


void ordenar_nombre(int n,char nombre[]){
	FILE *p;
	size_t n_alumnos;
	int j=0,f=0;
	char *puntero;
	char caracteres[100],vectorauxiliarP[10],vectorauxiliarS[10],vectorauxiliarT[10],vectorauxiliarC[10];
	int contador;
	alumnos alumno[n-2];
	p = fopen(nombre,"r");
	rewind(p);
	while (!feof(p))
 	    {
 		fgets(caracteres,100,p);
 		contador=0;
 		puntero = strtok (caracteres,":");
 		
 		while(puntero!=NULL) {
                switch(contador) {
                    case 0:
                        strcpy(alumno[j].apellido,puntero);
                        break;
                    case 1:
                        strcpy(alumno[j].nombre,puntero);
                        break;
                    case 2:
                        strcpy(vectorauxiliarP,puntero);
                        break;
                    case 3:
                        strcpy(vectorauxiliarS,puntero);
                        break;
                    case 4:
                        strcpy(vectorauxiliarT,puntero);
                        break;
                    case 5:
                        strcpy(vectorauxiliarC,puntero);
                        break;
                                                                 
            }
                contador++;
                puntero = strtok (NULL,":");
            }
 		
 		alumno[j].notalumno.Pparcial=atoi(vectorauxiliarP);
 		alumno[j].notalumno.Sparcial=atoi(vectorauxiliarS);
 		alumno[j].notalumno.Tparcial=atoi(vectorauxiliarT);
 		alumno[j].notalumno.Cparcial=atoi(vectorauxiliarC);
 		alumno[j].notalumno.promedio= (alumno[j].notalumno.Pparcial+alumno[j].notalumno.Sparcial+alumno[j].notalumno.Tparcial+alumno[j].notalumno.Cparcial)/4 ;
		j++;
		
 	    } 	    
 	    
 	    fclose(p);
        n_alumnos = sizeof(alumno)/sizeof(alumno[0]);
        for(f=0;f<j;f++){
        printf("%s:%s:%d:%d:%d:%d \n",alumno[f].apellido,alumno[f].nombre,alumno[f].notalumno.Pparcial,alumno[f].notalumno.Sparcial,alumno[f].notalumno.Tparcial,alumno[f].notalumno.Cparcial);
		}
		system("PAUSE");
        
        
        p = fopen (nombre, "w");
        rewind(p);
        
        qsort(alumno, n_alumnos, sizeof(alumnos), callback);
        
        
        
        
        for(f=0;f<j;f++){
        fprintf(p,"%s:%s:%d:%d:%d:%d \n",alumno[f].apellido,alumno[f].nombre,alumno[f].notalumno.Pparcial,alumno[f].notalumno.Sparcial,alumno[f].notalumno.Tparcial,alumno[f].notalumno.Cparcial);
		}
        fclose(p);
        
        return;
       }
       
       
int callback(const void *alumno_1, const void *alumno_2) {
    int retval;

    alumnos *al_1 = (alumnos*) alumno_1;
    alumnos *al_2 = (alumnos*) alumno_2;

    // Ordenación por nombre
    retval = strcmp(al_1->apellido, al_2->apellido);
    

    // Si los nombres son iguales se ordena por apellidos
    if(retval == 0)
		retval = strcmp(al_1->nombre, al_2->nombre);

    return retval;
}



       
void mostrarA(char nombre[],int i){
	FILE *p;
	char *puntero;
	char caracteres[100],vectorauxiliarP[10],vectorauxiliarS[10],vectorauxiliarT[10],vectorauxiliarC[10];
	int contador,cont=1;
	alumnos alumno;
 	
 	p = fopen(nombre,"r");
 	
 	if (p == NULL)
 		exit(1);
 	else
        {
 	    printf("\nLos Alumnos ingresados con sus promedios son : \n\n");
 	    rewind(p);
 	    while (!feof(p))
 	    {
 		fgets(caracteres,100,p);
 		contador=0;
 		puntero = strtok (caracteres,":");
 		
 		while(puntero!=NULL) {
                switch(contador) {
                    case 0:
                        strcpy(alumno.apellido,puntero);
                        break;
                    case 1:
                        strcpy(alumno.nombre,puntero);
                        break;
                    case 2:
                        strcpy(vectorauxiliarP,puntero);
                        break;
                    case 3:
                        strcpy(vectorauxiliarS,puntero);
                        break;
                    case 4:
                        strcpy(vectorauxiliarT,puntero);
                        break;
                    case 5:
                        strcpy(vectorauxiliarC,puntero);
                        break;
                                                                 
            }
                contador++;
                puntero = strtok (NULL,":");
            }
 		
 		alumno.notalumno.Pparcial=atoi(vectorauxiliarP);
 		alumno.notalumno.Sparcial=atoi(vectorauxiliarS);
 		alumno.notalumno.Tparcial=atoi(vectorauxiliarT);
 		alumno.notalumno.Cparcial=atoi(vectorauxiliarC);
 		alumno.notalumno.promedio= (alumno.notalumno.Pparcial+alumno.notalumno.Sparcial+alumno.notalumno.Tparcial+alumno.notalumno.Cparcial)/4 ;
 		if(cont<i){
 		printf("\n El alumno con apellido: %s  y Nombre: %s  tiene un promedio de %f .",alumno.apellido,alumno.nombre,alumno.notalumno.promedio);
 		cont++;
		}
 	    }


        }
        fclose(p);
	
	
	
	return;
}



int cargaralumno(char nombre[],int i){
	FILE *p;
	alumnos alumno;
	
	if(i==1){
	p = fopen (nombre, "w");
	}
	else{
	p = fopen (nombre, "a");
	}
	
	printf("\nIngrese el Apellido del alumno %d : ",i);
	fgets(alumno.apellido, 49, stdin);
	alumno.apellido[strlen(alumno.apellido)-1]='\0';
	
	printf("\nIngrese el Nombre del alumno %d : ",i);
	fgets(alumno.nombre, 49, stdin);
	alumno.nombre[strlen(alumno.nombre)-1]='\0';
	
	do{
	printf("\nIngrese la nota del 1er parcial del alumno : ");
	scanf("%d",&alumno.notalumno.Pparcial);
	fgetc(stdin);
	if(0>alumno.notalumno.Pparcial || 101<=alumno.notalumno.Pparcial){
		printf("Dato ingresado invalido. Por favor la nota es de 0 a 100.");
	}
	}while(0>=alumno.notalumno.Pparcial || 101<=alumno.notalumno.Pparcial);
	
	do{
	printf("\nIngrese la nota del 2er parcial del alumno : ");
	scanf("%d",&alumno.notalumno.Sparcial);
	fgetc(stdin);
	if(0>alumno.notalumno.Sparcial || 101<=alumno.notalumno.Sparcial){
		printf("Dato ingresado invalido. Por favor la nota es de 0 a 100.");
	}
	}while(0>=alumno.notalumno.Sparcial || 101<=alumno.notalumno.Sparcial);
	
	do{
	printf("\nIngrese la nota del 3er parcial del alumno : ");
	scanf("%d",&alumno.notalumno.Tparcial);
	fgetc(stdin);
	if(0>alumno.notalumno.Tparcial || 101<=alumno.notalumno.Tparcial){
		printf("Dato ingresado invalido. Por favor la nota es de 0 a 100.");
	}
	}while(0>=alumno.notalumno.Tparcial || 101<=alumno.notalumno.Tparcial);
	
	do{
	printf("\nIngrese la nota del 4er parcial del alumno : ");
	scanf("%d",&alumno.notalumno.Cparcial);
	fgetc(stdin);
	if(0>alumno.notalumno.Cparcial || 101<=alumno.notalumno.Cparcial){
		printf("Dato ingresado invalido. Por favor la nota es de 0 a 100.");
	}
	}while(0>=alumno.notalumno.Cparcial || 101<=alumno.notalumno.Cparcial);
	
	
	fprintf(p,"%s:%s:%d:%d:%d:%d \n",alumno.apellido,alumno.nombre,alumno.notalumno.Pparcial,alumno.notalumno.Sparcial,alumno.notalumno.Tparcial,alumno.notalumno.Cparcial);
	
	i++;
	
	fclose(p);
return i;	
}



char menu2(int i){
	char op;
	printf("\n\n\n\n");
	printf("\t\t\t\t\tMenu de opciones: \n\n");
	printf("\t\t\t\t\t1 -> Agregar Alumno %d y notas\n",i);
	printf("\t\t\t\t\t2 -> Ordenar por apellido y nombre\n");
	printf("\t\t\t\t\t3 -> Mostrar el promedio de cada alumno\n"); //debe mostrar apellido y nombre y el promedio
	printf("\t\t\t\t\t4 -> Transformar el archivo en csv\n");
	printf("\t\t\t\t\t9 -> Salir del programa\n\n");
	printf("\t\t\t\t\tSeleccionar una opcion: ");
	op = fgetc(stdin);	/*lee la opción ingresada por teclado*/
	if(op!='\n')
	fgetc(stdin);
	return op;
}

mollok
Mensajes: 521
Registrado: 30/01/2018 9:47 am
Ubicación: Mallorca, España

Re: No ordena alfabeticamente

#2 Mensaje por mollok » 06/08/2018 9:12 am

Lo he arreglado un poco:
Tabulaciones, tamaño de las líneas, nombre de variables: legibilidad
También he cambiado cómo se accede a los archivos y la forma de adquirir los datos. Hay funciones que realizan en trabajo mejor de las que habías elegido.
He cambiado también la estructura de las notas ya que el parcial no se guarda en el archivo no hace falta que esté en la estructura así que queda en una variable aparte.
Quedan cosas por hacer como el control de que el archivo existe en algunas funciones y deberías usar la función while(getchar()!='\n'); para vaciar el buffer en vez de un simple fgetc(stdin).

Código: Seleccionar todo

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
    int Pparcial;
    int Sparcial;
    int Tparcial;
    int Cparcial;
} notas;

typedef struct {
    char nombre[50];
    char apellido[50];
    notas notalumno;
} alumnos;

void cargaralumno(char archivo[]);
void mostrarA(char archivo[]);
void ordenar_nombre(char archivo[]);
char menu2();
int callback(const void *alumno_1, const void *alumno_2);

int main (int argc, char *argv[]) {
    char op;
    char archivo[]="estudiantes.txt";
    FILE *p;

    p = fopen (archivo, "r");
    if (p == NULL) {
        printf("\nEl archivo no existe, se creara con el nombre: %s.\n", archivo);
        p = fopen(archivo, "w+");
        if (p == NULL){
            printf("\nERROR: El archivo no se pudo crear ");
            exit(1);
        }
    }
    fclose(p);

    do {
        /*	system("clear");		*/
        op=menu2();                  /*menú retorna la opción elegida*/
        /*	system("clear");		*/

        switch(op) {
            case '1':
                cargaralumno(archivo);
                break;
            case '2':
                ordenar_nombre(archivo);
                break;
            case '3':
                mostrarA(archivo);
                break;
            case '4':
                printf ("El archivo donde se guardaron los datos se llama: '%s'.\n", archivo);			/**/
                break;
            case '9':
                printf("Fin del programa... ");
                break;
            default:
                printf("\n Opcion NO valida!");
                break;
        }
    } while(op!='9');

    return 0;
}

void ordenar_nombre(char archivo[]){
	FILE *p;
	size_t n_alumnos = 0;
	char c;

    p = fopen(archivo, "r");
    c = fgetc(p);
    while(!feof(p)) {
        if(c == '\n')
            ++n_alumnos;
        c = fgetc(p);
    }

    rewind(p);
    alumnos *alumno = malloc(sizeof(alumnos)*n_alumnos);
    for(int i=0; i<n_alumnos; ++i) {
        fscanf(p, "%[^:]:%[^:]:%d:%d:%d:%d\n", alumno[i].apellido, alumno[i].nombre,
                                            &alumno[i].notalumno.Pparcial,
                                            &alumno[i].notalumno.Sparcial,
                                            &alumno[i].notalumno.Tparcial,
                                            &alumno[i].notalumno.Cparcial);
    }

    fclose(p);

    // ---------------------------------------------------------------------
    for(int i=0; i<n_alumnos; i++) {
        printf("%s:%s:%d:%d:%d:%d\n", alumno[i].apellido, alumno[i].nombre,
                                      alumno[i].notalumno.Pparcial,
                                      alumno[i].notalumno.Sparcial,
                                      alumno[i].notalumno.Tparcial,
                                      alumno[i].notalumno.Cparcial);
    }
    system("PAUSE");
    // ---------------------------------------------------------------------

    qsort(alumno, n_alumnos, sizeof(alumnos), callback);
    p = fopen (archivo, "w");
    for(int i=0; i<n_alumnos; i++) {
        fprintf(p, "%s:%s:%d:%d:%d:%d\n", alumno[i].apellido, alumno[i].nombre,
                                          alumno[i].notalumno.Pparcial,
                                          alumno[i].notalumno.Sparcial,
                                          alumno[i].notalumno.Tparcial,
                                          alumno[i].notalumno.Cparcial);
    }
    free(alumno);
    fclose(p);
    return;
}

int callback(const void *alumno_1, const void *alumno_2) {
    int retval;
    alumnos *al_1 = (alumnos*) alumno_1;
    alumnos *al_2 = (alumnos*) alumno_2;

    // Ordenación por apellidos
    retval = strcmp(al_1->apellido, al_2->apellido);

    // Si los apelleidos son iguales se ordena por nombre
    if(retval == 0)
        retval = strcmp(al_1->nombre, al_2->nombre);
    return retval;
}

void mostrarA(char archivo[]) {
    FILE *p;
    alumnos alumno;
    char c;
    float promedio;

    p = fopen(archivo, "r");
    if(!p)
        exit(1);

    printf("\nLos Alumnos ingresados con sus promedios son : \n\n");

    c = fgetc(p);
    while(!feof(p)) {
        ungetc(c, p);

        fscanf(p, "%[^:]:%[^:]:%d:%d:%d:%d\n", alumno.apellido, alumno.nombre,
                                            &alumno.notalumno.Pparcial,
                                            &alumno.notalumno.Sparcial,
                                            &alumno.notalumno.Tparcial,
                                            &alumno.notalumno.Cparcial);
        promedio = (alumno.notalumno.Pparcial
                   +alumno.notalumno.Sparcial
                   +alumno.notalumno.Tparcial
                   +alumno.notalumno.Cparcial)/4;

        printf("\nEl alumno con %s, %s  tiene un promedio de %.2f .", alumno.apellido, alumno.nombre, promedio);

        c = fgetc(p);
    }
    fclose(p);
}

void cargaralumno(char archivo[]){
    FILE *p;
    alumnos alumno;

    p = fopen(archivo, "a");

    printf("\nIngrese el Apellido del alumno : ");
    fgets(alumno.apellido, 49, stdin);
    alumno.apellido[strlen(alumno.apellido)-1]='\0';

    printf("\nIngrese el Nombre del alumno : ");
    fgets(alumno.nombre, 49, stdin);
    alumno.nombre[strlen(alumno.nombre)-1]='\0';

    do {
        printf("\nIngrese la nota del 1er parcial del alumno : ");
        scanf("%d", &alumno.notalumno.Pparcial);
        fgetc(stdin);
        if(0>alumno.notalumno.Pparcial || 100<alumno.notalumno.Pparcial) {
            printf("Dato ingresado invalido. Por favor la nota es de 0 a 100.");
        }
    } while(0>alumno.notalumno.Pparcial || 100<alumno.notalumno.Pparcial);

    do {
        printf("\nIngrese la nota del 2o parcial del alumno : ");
        scanf("%d", &alumno.notalumno.Sparcial);
        fgetc(stdin);
        if(0>alumno.notalumno.Sparcial || 100<alumno.notalumno.Sparcial) {
            printf("Dato ingresado invalido. Por favor la nota es de 0 a 100.");
        }
    } while(0>alumno.notalumno.Sparcial || 100<alumno.notalumno.Sparcial);

    do {
        printf("\nIngrese la nota del 3er parcial del alumno : ");
        scanf("%d", &alumno.notalumno.Tparcial);
        fgetc(stdin);
        if(0>alumno.notalumno.Tparcial || 100<alumno.notalumno.Tparcial){
            printf("Dato ingresado invalido. Por favor la nota es de 0 a 100.");
        }
    } while(0>alumno.notalumno.Tparcial || 100<alumno.notalumno.Tparcial);

    do {
        printf("\nIngrese la nota del 4o parcial del alumno : ");
        scanf("%d",&alumno.notalumno.Cparcial);
        fgetc(stdin);
        if(0>alumno.notalumno.Cparcial || 100<alumno.notalumno.Cparcial){
            printf("Dato ingresado invalido. Por favor la nota es de 0 a 100.");
        }
    } while(0>alumno.notalumno.Cparcial || 100<alumno.notalumno.Cparcial);

    fprintf(p, "%s:%s:%d:%d:%d:%d\n", alumno.apellido, alumno.nombre,
                                      alumno.notalumno.Pparcial,
                                      alumno.notalumno.Sparcial,
                                      alumno.notalumno.Tparcial,
                                      alumno.notalumno.Cparcial);

    fclose(p);
}

char menu2(){
    char op;
    puts("\n\n\n");
    puts("\t\t\t\t\tMenu de opciones: \n");
    puts("\t\t\t\t\t1 -> Agregar nuevo alumno");
    puts("\t\t\t\t\t2 -> Ordenar por apellido y nombre");
    puts("\t\t\t\t\t3 -> Mostrar el promedio de cada alumno"); //debe mostrar apellido y nombre y el promedio
    puts("\t\t\t\t\t4 -> Transformar el archivo en csv");
    puts("\t\t\t\t\t9 -> Salir del programa\n");
    printf("\t\t\t\t\tSeleccionar una opcion: ");
    op = fgetc(stdin);	/*lee la opción ingresada por teclado*/
    if(op!='\n')
        fgetc(stdin);
    return op;
}
while(is_alive(yourself)) {
    make_true(yourself, yourdreams);
}

Avatar de Usuario
untio
Mensajes: 389
Registrado: 17/09/2008 9:35 am
Ubicación: Provincia de Almería
Contactar:

Re: No ordena alfabeticamente

#3 Mensaje por untio » 13/09/2018 1:18 pm

Permitidme que me entrometa una vez más.

Es una pena tener que decir esto una y otra vez, pero es que a veces es necesario:

NO SE PUEDEN ESCRIBIR TROPECIENTAS LINEAS DE CODIGO SIN PROBAR NI UNA VEZ LO QUE SE HA ESCRITO.

Si realmente se quiere tener éxito al crear programas informáticos hay que probar el código tantas veces como se pueda. Hasta el mejor programador del mundo mete la pata cada dos por tres. Lo que lo hace bueno es que cada parte de programa que hace la prueba para cada pequeño trozo comprobable que escribe. Aún así te puede quedar algún error, pero la mayoría te los habras cepillado, porque sabes en qué parte buscarlos (que es en el nuevo trozo que has escrito).

Tened en cuenta que, como dice un dicho: Un buen programa tiene un 5% de idea genial y un 95% de depuración.

Hasta luego.

Responder

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 5 invitados