Hello, I'm trying to do a data structures exercise in c, but there is an error and I can't find it. Follows the utterance and the code

4. Write, in C a system for registering and viewing students.

/ / / to store all students, implement a dynamic vector of pointers to structs, with the size of 100 records

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

#define qtdalunos 1

typedef struct{

char* nome;
char* matricula;
char* nascimento;
char* rg;

}aluno;

int i;

int main(){


aluno* alunos = (aluno*)malloc(sizeof(aluno)*100);

alunos->nome = (char*)malloc(50);
alunos->matricula = (char*)malloc(20);
alunos->nascimento = (char*)malloc(10);
alunos->rg = (char*)malloc(20);

void lerdados(aluno dados[qtdalunos]);
void printdados(aluno dados[qtdalunos]);

aluno classe[qtdalunos];

lerdados(classe);
printdados(classe);

free(alunos->nome);
free(alunos->matricula);
free(alunos->nascimento);
free(alunos->rg);
free(alunos);

alunos->nome = NULL;
alunos->matricula = NULL;
alunos->nascimento = NULL;
alunos->rg = NULL;
alunos = NULL;

getchar();
return 0;
}
void lerdados(aluno dados[qtdalunos]){

printf("\t\t Nome \\ Matricula \\ Data de Nascimento \\ RG ");

for(i=0; i<qtdalunos; i++){
    printf("\nInforme os dados do aluno %d:\n", i+1);
    scanf("%s %s %s %s", &dados->nome, &dados->matricula, &dados->nascimento, &dados->rg);
}

} void printdados (student data[qtdalunos]) {

printf("\t\t Nome\\Matricula\\Data de Nascimento\\Nota Final\\Frequencia\n");

for(i=0; i<qtdalunos; i++){
    printf("%s %s %s %s \n", &dados->nome, &dados->matricula, &dados->nascimento, &dados->rg);
}
}
Author: RXSD, 2019-09-06

1 answers

There are several errors in your code and since you haven't specified any in specific, we go step by step for each one.

  1. prototype of functions declared inside the main function body

You are declaring the prototype of the functions lerdados and printdados inside the main function body (main). Although some compilers accept this declaration, the most suitable is to declare the prototypes in one place before the function main and not inside hers.

  1. passing parameters to functions

The void lerdados(aluno dados[qtdalunos]) statement says that you will pass the array by value, which will cause problems in future allocations and releases for this vector. The correct one here would be to pass the array by reference and add an extra parameter informing the amount of positions that exist in it. The syntax would look like in the example below:

void lerdados(aluno dados[], int qtde);
void printdados(aluno dados[], int qtde);
  1. memory allocation outside the loop
aluno* alunos = (aluno*)malloc(sizeof(aluno)*100);
alunos->nome = (char*)malloc(50);
alunos->matricula = (char*)malloc(20);
alunos->nascimento = (char*)malloc(10);
alunos->rg = (char*)malloc(20);
lerdados(classe);

You declare an array of 100 positions, initialize the first position and call the function lerdados which will potentially try to read n positions, but pass the vector by value and not by reference. In addition, if you are going to read the data inside the loop, each student should preferably be allocated here as well.

void lerdados(aluno dados[qtdalunos]){
  printf("\t\t Nome \\ Matricula \\ Data de Nascimento \\ RG ");
  for(i=0; i<qtdalunos; i++){
      printf("\nInforme os dados do aluno %d:\n", i+1);
      scanf("%s %s %s %s", &dados->nome, &dados->matricula, &dados->nascimento, &dados->rg);
}
  1. reading data

Here you try to read 4 strings, but the syntax is wrong.

scanf("%s %s %s %s", &dados->nome, &dados->matricula, &dados->nascimento, &dados->rg)

See, %s needs a buffer address to place the text read by scanf. The syntax used (&dados->nome, for example) will always return the address of the first record. You would have to take into account the index of the loop. For example: &dados[i].nome.

  1. memory release out of loop

The same as the previous functions, you are releasing only 1 item from the vector. The program ends leaving the other 99 pointers for students still allocated.

I know it's a bit of a thing and the C language can get a little confusing at first, but don't be discouraged. Following is a working version of the code with all the fixes suggested above. Good studies.

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

#define QT_ALUNOS 2
#define MAX_ALUNOS 100
typedef struct {
    char* nome;
    char* matricula;
    char* nascimento;
    char* rg;
}aluno;

void lerdados(aluno dados[], int qtde);
void printdados(aluno dados[], int qtde);
void liberardados(aluno dados[], int qtde);

int main() {

    setlocale(LC_ALL, "pt-BR");  //para funcionar acentos e o ç

    aluno* classe = (aluno*) malloc(sizeof(aluno) * MAX_ALUNOS);
    lerdados(classe, QT_ALUNOS);
    printdados(classe, QT_ALUNOS);
    liberardados(classe, QT_ALUNOS);

    getchar();
    return 0;
}

void alocar_aluno(aluno *a) {
    a->nome = (char*)malloc(50);
    a->matricula = (char*)malloc(20);
    a->nascimento = (char*)malloc(10);
    a->rg = (char*)malloc(20);
}

void liberar_aluno(aluno* a) {
    free(a->nome);
    free(a->matricula);
    free(a->nascimento);
    free(a->rg);

    a->nome = NULL;
    a->matricula = NULL;
    a->nascimento = NULL;
    a->rg = NULL;
}

void lerdados(aluno dados[], int qtde){
    int i;  
    for (i = 0; i < qtde; i++) {
        aluno *item = &dados[i];
        alocar_aluno( item );
        printf("Informe os dados do aluno %i de %i:\n", i+1, qtde);
        printf("\tNome           : "); scanf("%s", item->nome);
        printf("\tMatrícula      : "); scanf("%s", item->matricula);
        printf("\tDt. Nascimento : "); scanf("%s", item->nascimento);
        printf("\tRG             : "); scanf("%s", item->rg);
        printf("\n");
    }
}

void printdados(aluno dados[], int qtde) {
    int i;
    printf("Listando os %i alunos da classe:\n", qtde);
    for (i = 0; i < qtde; i++) {
        printf("\t%i\tNome : %s, Matríula: %s, Dt. Nascimento: %s, RG: %s\n ", i,
            dados[i].nome,
            dados[i].matricula,
            dados[i].nascimento,
            dados[i].rg);
    }
}

void liberardados(aluno dados[], int qtde) {
    int i;  
    for (i = 0; i < qtde; i++) {
        liberar_aluno(&dados[i]);
    }
}

 0
Author: Fabiano Salles, 2019-09-06 19:11:58