How to order and print a list in C?

0

My question is how do I print the list of the 10 best students ( no students ) first I would have to sort the notes with a loop lower than 10? it has to be yes or yes with qsort ()? As I do to print the names of the students (not the numbers of the notes), here I leave the questions so they can better understand my code. The question I do not understand is only the No. 2, the others are already echos.

N1 °: Enter the data of the students of an establishment consisting of NAME (string of30 characters); Sex (char); AND NOTES of 10 coded subjects from 0 to 9 (int). The income will end when the name "FIN" is entered. It is known that the establishment does not have more than 1000 students.

N2 °: PRINT THE LIST OF THE 10 BEST STUDENTS. (THIS IS THE ONE WHO DID NOT START)

N ° 3: Indicate how many students are in the establishment whose average is greater than or equal to 4 and less than 7.

N ° 4: Allow the entry of a name and show the totality of your data, or if it does not belong to the establishment.

To sort the top 10 notes, look and I understand that it can be done with qsort () but I do not understand how to print the names of those notes and not the numbers

The code:

[code]

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

   #define MAX_ALUMNOS 3


   #define MAX_NOTAS 3

   struct alumno
   {
    char nombre[20];
    char sexo;
    int notas[MAX_NOTAS];
    float promedio_final;
    };

   char nombre_a_buscar[20];

int main()
{
struct alumno alumnos[MAX_ALUMNOS];
int num_alumnos;

for(num_alumnos=0; num_alumnos<MAX_ALUMNOS; num_alumnos++)
{
    printf("Nombre del alumno (para terminar teclee FIN): ");
    scanf("%s",alumnos[num_alumnos].nombre);
    if( strcmp(alumnos[num_alumnos].nombre,"FIN") == 0 )
        break;

    // else ....
    // nota que como el if tiene un break no es necesario el else
    do
    {
        char sexo;
        printf("Sexo: M o F: ");
        scanf("%s",&sexo);
        alumnos[num_alumnos].sexo = toupper(sexo);
    }

    while(alumnos[num_alumnos].sexo != 'M' && alumnos[num_alumnos].sexo !='F');
    float prom = 0.0;
    int sum = 0;

    for (int j=0; j<MAX_NOTAS; j++)
    {
        printf("Ingrese nota #%d: ",j+1);
        scanf("%d",&alumnos[num_alumnos].notas[j]);
        sum += alumnos[num_alumnos].notas[j];

    }
    prom = (float) sum / MAX_NOTAS;
    printf("Promedio de este alumno: %.2f \n", prom);


}

int total = 0;

for (int i=0; i<num_alumnos; i++)
{
    int suma = 0;
    float promedio = 0.0;

    for (int j=0; j<MAX_NOTAS; j++)
        suma += alumnos[i].notas[j];

    promedio = (float) suma / MAX_NOTAS;
    alumnos[i].promedio_final = promedio;

    if (promedio >= 4.0 && promedio < 7.0 )
        total++;
}

printf("Total de alumnos con promedio >= 4 y promedio < 7 = ");
printf("%d \n", total);

do
{
printf("Ingrese un nombre para mostrar datos: ");
scanf("%s", nombre_a_buscar);

bool hay_coincidencia = false;

for(int i=0;i<MAX_ALUMNOS;i++){

    if(strcmp(alumnos[i].nombre, nombre_a_buscar) == 0) {
        hay_coincidencia = true;
        printf("Nombre: %s \nSexo: %c \n", alumnos[i].nombre, alumnos[i].sexo);
        for(int j=0;j<MAX_NOTAS;j++)
            printf("Nota: #%d: %d \n", j+1, alumnos[i].notas[j]);
        printf("Promedio: %.2f \n", alumnos[i].promedio_final);
    }
}
if(!hay_coincidencia)
    printf("El nombre ingresado no se encuentra en la lista\n");
}
while(true);
return 0;
}

[/ code]

    
asked by Gabriel Forzza 31.10.2016 в 03:53
source

1 answer

1

qsort is a sort function that has the following signature:

void qsort (void* base, size_t num, size_t size,
            int (*compar)(const void*,const void*));

Where:

  • base : pointer to the first element to sort
  • num : number of elements to sort
  • size : size (in bytes) of each element
  • compar : pointer to function that allows to compare two elements

Basically what you have to do is create a function that receives two elements of type struct alumno that is able to indicate which should go ahead in the sort. For this you must calculate the average of each student. In this case I would create a second function that would return the sum of the notes (I hate repeating code):

int suma_notas(struct alumno* alumno)
{
  int total = 0;
  for( int i=0; i<MAX_NOTAS; i++ )
    total += alumno->notas[i];

  return total;
}

Note: I could have done the same if I returned the average ... but the average is only a division that does not contribute anything (if the sum of the notes is greater the average will be equally greater).

Now what we are interested in is that the students with the best averages are at the top of the list. For this you have to return the following:

  • X 0 if the first element goes after the second

Said with numbers. We want the ones with the best grades to stay on top. If, for example, we have a student with a sum = 10 and another with a sum = 11, we will have to return a number> 0, then we can solve the problem with a simple subtraction: 11-10 = 1> 0, then it is enough to subtract the second student the sum of the first notes:

int OrdenarPorPromedio(const void* alumno1, const void* alumno2)
{
  int suma1 = suma_notas((struct alumno*)alumno1);
  int suma2 = suma_notas((struct alumno*)alumno2);

  return suma2 - suma1;
}

As you can see, the ugly part of using qsort is that the parameters are pointers to void, so in order to access members of struct alumno we must cast.

We already have everything necessary to order our list:

qsort(alumnos,num_alumnos,sizeof(struct alumno),OrdenarPorPromedio);

After this you can focus on the first 10 students and that will be the result of the problem.

    
answered by 31.10.2016 в 08:53