单个链接列表上的最后一个不希望的节点

问题描述 投票:0回答:1

我正在尝试从文件中获取数据并将其放在单个链表中。但是,我的功能是创建最后一个不良节点。我想这是缓冲区的问题,但是我不知道如何摆脱它。谁能告诉我为什么我有这个额外的节点?

/* notas.h */

#ifndef _PROVA06_  /* Inicio da diretiva do pre-processador. */
#define _PROVA06_  "@(#)notas.h $Revision$"

/* Definicao das macros. */

#define COMPRIMENTO_DA_MEDIA                    4
#define COMPRIMENTO_DO_DRE                      9
#define COMPRIMENTO_MAXIMO_DO_BUFFER            9
#define EOS                                    '\0'

/* Codigos de retorno. */

#define OK                                          0
#define NUMERO_DE_ARGUMENTOS_INVALIDO               1

/* Definicao do tipo enumerado boolean. */

typedef enum
{
  falso = 0,
  verdadeiro = 1
} boolean;

/* Definicao do tipo estruturado tipoMediasAlunos a partir da estrutura 
estruturaMediasAlunos. */

typedef struct estruturaMediasAlunos
{
  char dre[COMPRIMENTO_DO_DRE + 1];  /* 9 + 1 */
  float media;
  struct estruturaMediasAlunos *proximo;
} tipoMediasAlunos;

/* Prototipo da funcao ObterMediasAlunos. */

tipoMediasAlunos *
ObterMediasAlunos(char *);

#endif

Notas.c

/* notas.c */

/* Inclusao dos arquivos de cabecalho da biblioteca padrao do sistema. */

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

/* Inclusao do arquivo de cabecalho personalizado para a prova. */

#include "notas.h"

/* Implementacao da funcao ObterMediasAlunos. */

tipoMediasAlunos *
ObterMediasAlunos(char *nomeArquivoBinario)
{

  /* Utilizacao de variaveis locais dentro da funcao ObterMediasAlunos. */

  FILE *arquivoBinario;
  char buffer[COMPRIMENTO_MAXIMO_DO_BUFFER];
  boolean teste = falso;
  tipoMediasAlunos *alunoInicial, *proximoAluno;
  char *validacao;

  /* */

  alunoInicial = (tipoMediasAlunos *) malloc(sizeof(tipoMediasAlunos));

  /* Verificacao da existencia de argumento nulo. */

  if (!nomeArquivoBinario)
    return NULL;  /* 0 */

  /* Verificacao da existencia de argumento vazio. */

  if (*nomeArquivoBinario == EOS)
    return NULL;  /* 0 */

  /* */

  proximoAluno = alunoInicial;

  /* Abertura para leitura do arquivo do tipo binario. */

  arquivoBinario = fopen(nomeArquivoBinario, "rb");

  /* Verificacao de erro na abertura para leitura do arquivo do tipo binario. */

  if (!arquivoBinario)
    return NULL;  /* 0 */

  /* Varredura pelo arquivo do tipo binario. */

  while (fgets(buffer, (COMPRIMENTO_MAXIMO_DO_BUFFER + 1), arquivoBinario) != NULL)
  {

    /* Verificacao de erro no arquivo do tipo binario. */

    if (teste == verdadeiro)  /* if (teste)*/
    {
      fclose(arquivoBinario);
      return NULL;  /* 0 */
    } /* if */


    /* */

    strcpy(proximoAluno->dre, buffer);
    fgets(buffer, (COMPRIMENTO_DA_MEDIA + 1), arquivoBinario);
    proximoAluno->media = strtof(buffer, &validacao);


    /* */

    proximoAluno->proximo = (tipoMediasAlunos *) 
    malloc(sizeof(tipoMediasAlunos));
    proximoAluno = proximoAluno->proximo;

  } /* while */

  /* */

  proximoAluno->proximo = NULL;
  proximoAluno = alunoInicial;

  /* */

  while (proximoAluno->proximo != NULL)
  {
    printf("%s\n", proximoAluno->dre);
    printf("%.1f\n\n", proximoAluno->media);
    proximoAluno = proximoAluno->proximo;
  } /* while */

  /* */

  if (ferror(arquivoBinario))
  {
    fclose(arquivoBinario);
    return NULL;  /* 0 */
  } /* if */

  /* */

  if (fclose(arquivoBinario) != 0)
    return NULL;  /* 0 */

  return alunoInicial;

} /* ObterMediasAlunos */

testeMedia.c

/* testeMedia.c */

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

/* */

#define NUMERO_DE_ARGUMENTOS                    2





/* */

int
main (int argc, char **argv)
{

  /* */

  printf("\n\n\n");

  /* */

  (*ObterMediasAlunos)(*(argv + 1));


  /* */

  /* printf("\n\n\n\n"); */



  return OK;  /* */

} /* main */

编译和链接

UBUNTU 00 --> gcc -Wall -std=c11 -c notas.c
UBUNTU 00 --> gcc -Wall -std=c11 -c testeMedia.c 
UBUNTU 00 --> gcc -Wall -std=c11 -o testeMedia notas.o testeMedia.o

输出

UBUNTU 01 --> ./testeMedia medias_finais_binario



111239451
3.7

113277049
2.7

115092005
1.9


0.0

UBUNTU 01 -->

medias_finais_binario

11123945103.711327704902.711509200501.9^@
c struct linked-list buffer binaryfiles
1个回答
0
投票

您正在为下一行数据(proximoAluno)分配节点之前,您知道是否需要它(在循环结束时。)>

仅应在循环开始时知道要存储的数据行后分配节点。确保正确处理第一行。

  alunoInicial = NULL;
  proximoAluno = NULL;
  while (fgets(buffer, (COMPRIMENTO_MAXIMO_DO_BUFFER + 1), arquivoBinario) != NULL)
  {

    /* Verificacao de erro no arquivo do tipo binario. */

    if (teste == verdadeiro)  /* if (teste)*/
    {
      fclose(arquivoBinario);
      return NULL;  /* 0 */
    } /* if */


    /* */

    if (alunoInicial == NULL) {
        alunoInicial = malloc(sizeof(tipoMediasAlunos));
        proximoAluno = alunoInicial;
    } else {
        proximoAluno->proximo = malloc(sizeof(tipoMediasAlunos));
        proximoAluno = proximoAluno->proximo;
    }
    proximoAluno->proximo = NULL;

    strcpy(proximoAluno->dre, buffer);
    fgets(buffer, (COMPRIMENTO_DA_MEDIA + 1), arquivoBinario);
    proximoAluno->media = strtof(buffer, &validacao);


    /* */

  } /* while */

请注意,不需要强制转换从malloc返回的指针,并且将每个已分配节点的proximo指针设置为NULL。

© www.soinside.com 2019 - 2024. All rights reserved.