Help Structura and Vector in C, simple program of students and notes

How to make a vector? How do I not put nota1;nota2;nota3;etc? I made 2 codes, but they don't work for me. How to do with the topic of average?

1) Enter student data from an establishment consisting of NOMBRE (string 30 characters), SEXO (char), and NOTAS from 10 encoded subjects from 0 to 9 (int). The income will end when you enter the name FIN.

2) indicate the number of students in the establishment whose average is greater than or equal to 4 and less than 7.

Transcript of the photocopy they asked to make:

  1. enter consistent student data from an establishment in name (string of 30 characters), gender (char) and notes of 10 subjects coded from 0 to 9 (int). The income will end when enter the name "end". It is known that the establishment has no more of 10,000 students.
  2. print the list top 10 students.
  3. indicate how many students are in the establishment whose average is greater than or equal to 4 and less than seven.
  4. allow the entry of a name and display all of its data, or, if it does not belong to the establishment.

Code 1:

#include stdio.h
#include stdlib.h
#include ncurses.h
#include string.h

struct promedio{
    int nota1;
    int nota2;
    int nota3;
    int nota4;
    int nota5;
    int nota6;
    int nota7;
    int nota8;
    int nota9;
    int nota10;
};

struct alumno{
    char nombre[20];
    char sexo[20];
    int edad;
    struct promedio prom;
}alumnos[100];

int main(){
    int n,i,pmay;
    int promedio[100], mayor = 0;
    printf("Digite el total de alumnos: ");
    scanf("%i",&n);

    for(i=0;i<n;i++){

        printf("%i. Digite su nombre: ",i+1);
        scanf("%s",alumnos[i].nombre);
        printf("%i. Digite su sexo: ",i+1);
        scanf("%s",alumnos[i].sexo);
        printf("%i. Digite sus notas: ",i+1);
        scanf("%i %i %i %i %i %i %i %i %i %i",&alumnos[i].prom.nota1,
        &alumnos[i].prom.nota2,&alumnos[i].prom.nota3,&alumnos[i].prom.nota4,
      &alumnos[i].prom.nota5,&alumnos[i].prom.nota6,&alumnos[i].prom.nota7,&alumnos[i].prom.nota8,
      &alumnos[i].prom.nota9,&alumnos[i].prom.nota10);
        printf("\n");

        promedio[i] = (alumnos[i].prom.nota1+alumnos[i].prom.nota2+alumnos[i].prom.nota3+alumnos[i].prom.nota4+alumnos[i].prom.nota5+
        alumnos[i].prom.nota6+alumnos[i].prom.nota7+alumnos[i].prom.nota8+alumnos[i].prom.nota9+alumnos[i].prom.nota10)/3;

        if(promedio[i] > mayor){
            mayor = promedio[i];
            pmay = i;
        }
    }

    printf("\n- El Alumno con Mayor Promedio-\n");
    printf("\nNombre: %s",alumnos[pmay].nombre);
    printf("\nSexo: %s",alumnos[pmay].sexo);
    printf("\nPromedio: %i\n",promedio[pmay]);


    getch();
    return 0;
}

Code 2:

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

#define MAX 100

struct {
    char nombre[20];
    char sexo;
    int notas[10];
} alumno[MAX];

int main() {
    int j,i=0,suma,a,b,c;
    float promedio=0.0;

    while (1) {
        printf("Nombre del alumno (para terminar teclee FIN): ");
        scanf("%s",alumno[i].nombre);
        getchar();

        if (strcmp(alumno[i].nombre,"FIN") == 0)
            break;
        else {
            printf("Sexo: M o F: ");
            scanf("%c",&alumno[i].sexo);
            for (j=0; j<10; j++) {
                printf("Ingrese nota # %d: ",j+1);
                scanf("%d",&alumno[i].notas[j]);
            }
        }
        printf("\n");
        i += 1;
    }

    for (a=0; a<i; a++) {
        suma = 0;
        for (b=0; b<10; b++)
            suma = suma+alumno[a].notas[b];

        promedio = suma/3;
        if (promedio >= 4 && promedio < 7)
            c += 1;
    }
    printf("Total de alumnos con promedio >= 4 y promedio < 7 = ");
    printf("%d",c);

    return 0;
}
 2
Author: Eslacuare, 2016-10-26

3 answers

The problem that the first proposal has is that it is complicated to do averaging because you can't stuff a loop. The best option would be to make use of the second, which also has less code:

#define MAX_NOTAS 10

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

On the other hand, in the statement they are telling you the following:

Enter the student data of an establishment consisting of name (30 character string), gender (char) and grades of 10 subjects encoded from 0 to 9 (int). Income it will end when the name "End"is entered. it is known that the establishment has no more than 10000 students.

In the highlighted part you are already given a limit of students. The first thing you have to do is reserve enough space to store that number of items. I personally would avoid making use of global variables since in the long run they will give you more problems than joys. It would also avoid introducing literals between the Code:

#define MAX_ALUMNOS 10000

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

El loop to enter students must end when the word "FIN" is entered, although since we have a limit of students it would not hurt to verify that we do not exceed this limit even if by mistake:

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
}

When you learn to program you realize that you have to treat the user as if he were a complete useless and could always be confused... imagine that the one who is going to use the program is a monkey that pummels the keyboard... you have to check everything that is entered to know if it is valid:

do
{
  char sexo;
  printf("Sexo: M o F: ");
  scanf("%c",&sexo);
  alumnos[num_alumnos].sexo = toupper(sexo);
} while( alumnos[num_alumnos].sexo != 'M' && alumnos[num_alumnos].sexo !='F');

And finally, to enter the notes, we can make use of the constant that we have declared at the beginning (the grace of using constants is that if we want to do quick tests you only have to change values in one site);

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

Now we review the average:

for (int i=0; i<; a++) {
  suma = 0;
  for (b=0; b<10; b++)
    suma = suma+alumnos[a].notas[b];

  int promedio = suma/3; // <<--- AQUI!!!
  if (promedio >= 4 && promedio < 7)
    c += 1;
}

Why do you divide the sum by 3? Have we not stayed on that it is 10 notes? This is one of the problems associated with using literals in Code:

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

  promedio = suma/MAX_NOTAS;

  // Esto ...
  if (promedio >= 4 && promedio < 7)
    resultado++;
  // ... es equivalente a ...
  resultado += (promedio >= 4 && promedio < 7);
}

And with these changes the program should work for you.

A greeting.

 3
Author: eferion, 2016-10-26 07:56:00

The idea of this forum is to raise specific questions about specific programming problems. Questions asking for answers on how to solve an entire exercise are usually not well received, I also give you some help so that you can solve it.

The structure you should use is as follows:

Struct alumno {
    char nombre[30];
    char sexo;
    int notas[10];
    float promedio;
};

For sex it is not necessary to use a vector, since the Get asks you a char. I assume that men will carry an M in that field and women an F. For the notes it is not necessary to create a structure like you were doing, what I did was put a vector inside the structure that will contain the 10 notes of each student. I also added a variable of type float where the average of the 10 notes will be saved.

The first thing you have to do is take care of the load of the students, as you do not know how many students will be forcibly entered you will have to use Dynamic Memory.

For this, the first thing that you have to do is declare a variable of type Student:

struct alumno primer_dato;

Then you ask the user to enter the student's name. If the name is different from end (end condition according to the setpoint), you store the name in the created variable and ask the user to enter the gender and the 10 notes (there you calculate the average) and insert all the data in the same structure. At that point you will have the entire structure loaded and you will have to ask for memory using the malloc function, to then add the node to a list that you will need to create. This process will always be repeated until the name entered is finished.

When your list is fully loaded with all students, you can continue with points 2, 3 and 4 of your instruction.

 0
Author: cventu, 2016-10-26 03:22:27

How to make a vector? How do I not put nota1;nota2;nota3;etc?

I deduce (maybe erroneously) that you want to know how to make a vector in dynamic memory, since in other parts of your code I see that you already know how to make vectors in static memory.

To create a dynamic memory vector you must use the function malloc, which is responsible for hosting memory (memory alloc ation).

The function malloc belongs to the header <stdlib.h>:

void* malloc( size_t recuento_de_bytes ); 

Hosts recuento_de_bytes bytes of uninitialized memory (that is, it will contain data with indeterminate values). If you manage to host the requested memory, a pointer will be returned to the start of the requested memory block.

So if you want 10 integer values for your average you should do the following:

// Aloja memoria para 10 int
int *promedio = malloc(10 * sizeof(int));

The statement sizeof(int) returns the size of the type int, which is usually 4 bytes (on most 32-bit systems) so the number of bytes needed to host 10 integers would be 40 bytes (10 * sizeof(int)).

You can access each of the 10 integers using the brackets ([ and ]) counting that the first integer is index 0 and the last IS index 9:

/* Ponemos todos los datos a 0 porque
malloc devuelve memoria no inicializada. */
for (int indice = 0; indice < 10; ++indice)
    promedio[indice] = 0;

Do not forget that the memory requested by malloc is not released unless so indicated. To free the memory you have to use the function free:

void free( void* puntero_a_memoria_dinamica );

Also belongs to the header <stdlib.h> and will release the dynamically requested memory, for this you have to pass the pointer pointing to the beginning of the block of memory that was dynamically requested.

Enter student data from an establishment consisting of NOMBRE (string 30 characters), SEXO (char), and NOTAS from 10 encoded subjects from 0 to 9 (int). The income will end when you enter the name FIN.

As far as I can see this you have it almost fixed, but you don't check to get the name FIN to stop asking for data. To compare the entered text against a given text you must use strcmp or better strncmp, both belong to the header <string.h>.

strcmp it is a string comparison function, it receives a pointer to the first character to compare from the first string and a pointer to the first character to compare from the second string. The result is an integer:

int strcmp( const char *cadena_izquierda, const char *cadena_derecha );

El result you can get the values -1, 0 or 1 depending on the result of the comparison: cadena_izquierda less than cadena_derecha, cadena_izquierda and cadena_derecha equal to or cadena_izquierda greater than cadena_derecha respectively.

strncmp it is the secure version of strcmp that adds a parameter with the maximum number of characters to compare:

int strncmp( const char *cadena_izquierda, const char *cadena_derecha, size_t maximo );

Knowing that NOMBRE will always be a string of 30 characters you could use this function.

Indicate the number of students in the establishment whose average is greater than or equal to 4 and less than 7.

Once you have all the notes in your vector, you will only have to loop through them and count the number of elements that meet the condition:

int promedio_entre_4_y_7 = 0;

for (int indice = 0; indice < cantidad_de_alumnos; ++indice)
    if ((promedio[indice] >= 4) && (promedio[indice] < 7))
        ++promedio_entre_4_y_7;

In the condition I have put parentheses between each of the comparisons but it is not necessary for the operator precedence since >= and < have precedence greater than &&.

 0
Author: PaperBirdMaster, 2016-10-26 07:58:42