Sequential reading of data from a file

Asked

Viewed 30 times

-1

I have to read a file in which the first line represents the number of registered students and in the following lines occurs the name of the student followed by his grade in the two tests. It seems to me that the problem is in reading the file, but I have tried several ways to remedy the problem but it persists. File example:

3
ZE CARLOS
8.5
10.0
ANTONIO SANTOS
7.5
8.5
SEBASTIAO OLIVEIRA
5.0
6.0
int main()
{
    FILE *pFile;

    char nomearq[25];
    float *medias, temp1=0, temp2=0;
    int qntalunos, i, j;

    printf("Entre com o nome do arquivo no qual as informacoes estao armazenadas: ");
    fflush(stdin);
    gets(nomearq);

    //Abertura do arquivo em modo de leitura
    pFile=fopen(nomearq, "r");

    //Verificacao
    if(pFile==NULL)
    {
        printf("\nErro em abrir o arquivo\n\n");
        exit(1);
    }
    else
    {
        printf("\nArquivo aberto com sucesso\n\n");
    }

    //Adquirindo a quantidade de alunos presente no arquivo
    fscanf(pFile,"%d", &qntalunos);

    char nomes[qntalunos][50];

    //Alocando dinamicante
    medias=(float *)malloc(qntalunos*sizeof(float));

    //Verificando
    if(medias==NULL)
    {
        printf("\nErro na alocacao dinamica do vetor de medias\n\n");
        exit(1);
    }

    //Lendo o arquivo
    for(i=0; i<qntalunos; i++)
    {
        fgets(nomes[i],50, pFile);
        fscanf(pFile,"%f", &temp1);
        fscanf(pFile,"%f", &temp2);
        medias[i]=(temp1+temp2)/2.0;
    }

    printf("Alunos abaixo da media:\n\n");
    for(i=0; i<qntalunos; i++)
    {
        if(medias[i]<7.0)
        {
            printf("Nome: %s\n", nomes[i]);
            printf("Media: %.2f\n", medias[i]);
        }
    }

    fclose(pFile);
    free(medias);

    return 0;
}
  • What exactly is the error of the programme? when implementing what the programme does wrong?

  • None of the data is being stored correctly, I tried to print them later, for example the medias array, and there is nothing or some crazy numbers appear. Same with the name array

1 answer

0

Assuming that your input file alunos.txt be something like:

5
ZE CARLOS
8.5
10.0
ANTONIO SANTOS
7.5
8.5
SEBASTIAO OLIVEIRA
5.0
6.0
ISAAC NEWTOW
4.0
2.5
ALBERT EINSTEIN
10.0
10.0

We can abstract the record of a Aluno using a struct to facilitate the manipulation and readability of the code, let us see:

struct aluno_s
{
    char  nome[50];
    float nota1;
    float nota2;
};

typedef struct aluno_s aluno_t;

Now, we can implement the function capable of reading the data of a given file and storing them completely in memory:

int alunos_carregar( const char * arquivo, aluno_t ** alunos )
{
    FILE * arq = NULL;
    int qtd_alunos = 0;
    char linha[ LINHA_MAX_TAM + 1 ] = {0};
    aluno_t * p = NULL;
    int i = 0;

    /* abre o arquivo de alunos */
    arq = fopen( arquivo, "r");

    if( !arq )
        return -1;

    /* le a primeira linha do arquivo */
    if(!fgets( linha, LINHA_MAX_TAM, arq ))
        goto erro_fatal;

    /* converte a linha lida para um inteiro representando a
     * quantidade alunos no arquivo*/
    qtd_alunos = atoi(linha);

    /* aloca memoria necessaria para acomodar os alunos
     * que serao lidos */
    p = (aluno_t*) malloc( qtd_alunos * sizeof(aluno_t) );

    if(!p)
        goto erro_fatal;

    /* Para cada aluno no arquivo... */
    for( i = 0; i < qtd_alunos; i++ )
    {
        /* le a linha contendo o nome do aluno */
        if(!fgets( linha, LINHA_MAX_TAM, arq ))
            goto erro_fatal;

        /* remove os finalizadores de linha contidos no buffer */
        linha[strcspn(linha, "\r\n")] = 0;

        /* copia o nome do aluno para a memoria */
        strncpy( p[i].nome, linha, NOME_ALUNO_MAX_TAM );

        /* le a linha que representa a primeira nota do aluno */
        if(!fgets( linha, LINHA_MAX_TAM, arq ))
            goto erro_fatal;

        /* converte a linha lida para um float */
        p[i].nota1 = atof(linha);

        /* le a linha que representa a segunda nota do aluno */
        if(!fgets( linha, LINHA_MAX_TAM, arq ))
            goto erro_fatal;

        /* converte a linha lida para um float */
        p[i].nota2 = atof(linha);
    }

    /* fecha o arquivo de alunos */
    fclose(arq);

    /* retorna lista de alunos usando o ponteiro para
     * ponteiro passado com argumento */
    *alunos = p;

    /* retorna a quantidade de alunos na lista */
    return qtd_alunos;

erro_fatal:

    if(arq)
        fclose(arq);

    if(p)
        free(p);

    *alunos = NULL;

    return -1; /* erro fatal */
}

Once we have the data well structured in memory, we can think about the function capable of displaying it on the screen:

void alunos_exibir( aluno_t * alunos, int qtd_alunos, float media_min )
{
    int i = 0;
    float media = 0.0;

    /* para cada aluno... */
    for( i = 0; i < qtd_alunos; i++ )
    {
        /* calcula a media do aluno */
        media = (alunos[i].nota1 + alunos[i].nota2) / 2.0;

        /* se a media for menor que a media minima, exibe aluno */
        if( media < media_min )
        {
            printf( "Nome: %s\n", alunos[i].nome );
            printf( "  Nota1: %0.2f\n", alunos[i].nota1 );
            printf( "  Nota2: %0.2f\n", alunos[i].nota2 );
            printf( "  Media: %0.2f\n", media );
            printf( "\n" );
        }
    }
} 

And finally, our main() would look something like this:

int main( void )
{
    aluno_t * alunos = NULL;
    int qtd = 0;

    qtd = alunos_carregar( "alunos.txt", &alunos );

    if( qtd < 0 )
    {
        printf("Erro ao abrir o arquivo de entrada.\n");
        return EXIT_FAILURE;
    }

    alunos_exibir( alunos, qtd,  7.0 );

    free( alunos );
    return EXIT_SUCCESS;
}

Exit:

Nome: SEBASTIAO OLIVEIRA
  Nota1: 5.00
  Nota2: 6.00
  Media: 5.50

Nome: ISAAC NEWTOW
  Nota1: 4.00
  Nota2: 2.50
  Media: 3.25

See working on repl it.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.