# Help Structura and Vector in C, Simple program of Students and Notes

1

How to make a vector? In what way do you do not go putting `nota1;nota2;nota3;etc` ? I made 2 codes, but they do not work for me. How to do with the theme of the average?

1) Enter the data of the students of an establishment consisting of `NOMBRE` (string 30 characters), `SEXO` (char), and `NOTAS` of `10` coded materials of `0` a `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:

• Enter the data of the students of a consistent establishment   in NAME (string of 30 characters), SEX (char) and NOTES of 10   coded materials from 0 to 9 (int). The income will end when it   enter the name "END". It is known that the establishment has no more   of 10,000 students.
•
• Print the list of the 10 best students.
•
• Indicate how many students are in the establishment whose average is   greater than or equal to 4 and less than seven.
•
• Allow 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];
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;
}
``````

asked by Gabriel Forzza 26.10.2016 в 04:13
source

2

The problem with the first proposal is that it is complicated to calculate averages because you can not put a loop. The best option would be to use the second one, 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 you are saying the following:

Enter the data of the students of an establishment consisting of NAME (string of 30 characters), SEX (char) and NOTES of 10 coded subjects from 0 to 9 (int). The deposit will end when the name "FIN" is entered. It is known that the establishment does not have more than 10,000 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 entering literals between the code:

``````#define MAX_ALUMNOS 10000

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

The loop to introduce students must end when the word `"FIN"` is entered, although since we have a cap of students it would not hurt to verify that we do not exceed this limit even if it is in error:

``````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 it were a complete useless and could always be confused ... imagine that who is going to use the program is a monkey that pound 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 introduce the notes, we can make use of the constant that we have stated at the beginning (the grace of using constants is that if we want to do quick tests you only have to change values in a 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? We have not been in what are 10 notes? This is one of the problems associated with the use of literals in the 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)
// ... es equivalente a ...
resultado += (promedio >= 4 && promedio < 7);
}
``````

And with these changes the program should work for you.

Greetings.

0

The idea of this forum is to raise specific doubts about specific programming problems. The questions asking for answers on how to solve a whole exercise are generally not well received, I also throw some help so you can solve it.

The structure you should use is the following:

``````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 for a char. I assume that men will wear an M in that field and women an F. For the notes it is not necessary to create a structure as you were doing, what I did was to put a vector inside the structure that will contain the 10 notes of each student. I also added a variable of the float type where the average of the 10 notes will be stored.

The first thing you have to do is take care of the load of the students, since you do not know how many students are going to enter you will have to use dynamic memory.

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

``````struct alumno primer_dato;
``````

Then you ask the user to enter the name of the student. If the name is different from FIN (condition of completion according to the slogan), you store the name in the created variable and ask the user to enter the sex and the 10 notes (there you calculate the average) and insert all the data in it structure. At that moment you will have the whole structure loaded and you will have to ask for memory using the malloc function, and then add the node to a list that you will have to create. This process will always be repeated until the name entered is FIN.

When you list is completely loaded with all the students, you can continue with points 2, 3 and 4 of your slogan.

0

How to make a vector? In what way do you do not put `nota1;nota2;nota3;etc` ?

I assume (maybe wrongly) 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 vector in dynamic memory you should use the `malloc` function, which is responsible to store memory ( `m` emory `alloc` ation).

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

``````void* malloc( size_t recuento_de_bytes );
``````

It hosts% co_of% bytes of uninitialized memory (that is: it will contain data with undetermined values). If it manages to host the requested memory, a pointer will be returned at the beginning of the requested memory block.

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

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

The `recuento_de_bytes` instruction returns the size of type `sizeof(int)` , which is usually 4 bytes (in most 32-bit systems) so the number of bytes needed to accommodate 10 integers would be 40 bytes ( `int` ).

You can access each of the 10 integers using the brackets ( `10 * sizeof(int)` and `[` ), counting that the first integer will be the index 0 and the last the 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 `]` is not released unless indicated. To free the memory you have to use the function `malloc` :

``````void free( void* puntero_a_memoria_dinamica );
``````

It also belongs to the header `free` and it will release the dynamically requested memory, for this it is necessary to pass the pointer pointing to the beginning of the block of the memory that was requested dynamically.

Enter the data of the students of an establishment consisting of `<stdlib.h>` (string 30 characters), `NOMBRE` (char), and `SEXO` of `NOTAS` coded materials of `10` to `0` (int ). The income will end when you enter   the name `9` .

As far as I can see this you have almost solved it, but do not check that you enter the name `FIN` to stop asking for data. To compare the text entered against a certain text you must use `FIN` or better `strcmp` , both belong to the header `strncmp` .

`<string.h>` is a character 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 );
``````

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

`cadena_derecha` is the secure version of `strncmp` 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 `strcmp` 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 `NOMBRE` and less than `4` .

Once you have all the notes in your vector, you only have to go 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 precedence of operators since `7` and `>=` have a precedence greater than `<` .