我正在尝试从文件中获取数据并将其放在单个链接列表中。但是,我的函数正在创建最后一个不需要的节点。我想这是缓冲区的问题,但我不知道如何摆脱它。谁能告诉我为什么我有这个额外的节点?
/* 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 ' '
/* 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("%sn", proximoAluno->dre);
printf("%.1fnn", 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("nnn");
/* */
(*ObterMediasAlunos)(*(argv + 1));
/* */
/* printf("nnnn"); */
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^@
在知道是否需要之前(在循环结束时(,您正在为下一行数据(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。