As operações que poderão ser realizadas sobre a base de dados são i) adição/edição de um aluno; ii) busca de um aluno; iii) remoção de um aluno; e iv) impressão de um registro. As funções para estas operações estão em um arquivo separado da função main. Neste laboratório, não há a necessidade de se preocupar com a entrada, apenas com a manipulação do vetor passado por parâmetro.
A base de dados é implementada com um vetor que é alocado dinamicamente.
O registro com as informações de um aluno deverá ser implementado como um struct.
Exemplo de entrada:
2
> 190029
+ 190029 99009912 Paulo da Silva
> 190029
+ 210419 91889912 Maria Souza
q
Exemplo de saída:
Base criada.
Aluno 190029 nao encontrado.
Adicionado: 190029 - 99009912 - Paulo da Silva
190029 - 99009912 - Paulo da Silva
Adicionado: 210419 - 91889912 - Maria Souza
Arquivo com a função main (autoria dos PEDs do IC-Unicamp):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
int ra, telefone;
char nome[100];
} Registro;
typedef struct {
int armazenado;
int capacidade;
Registro *registros;
} Base;
void criar_base(Base *base, int n);
int buscar(Base *base, int ra);
void imprimir(Base *base, int ra);
void adicionar(Base *base, int ra, int telefone, char *nome);
void remover(Base *base, int ra);
void limpar(Base *base);
void liberar_base(Base *);
int main() {
Base base;
int capacidade;
if (scanf("%d\n", &capacidade) != 1) {
printf("Erro de Leitura da Capacidade\n");
return 1;
}
criar_base(&base, capacidade);
if (base.capacidade != capacidade) {
printf("Capacidade inicial errada: %d\n", base.capacidade);
}
if (base.armazenado != 0) {
printf("Quantidade armazenada inicial errada: %d\n", base.armazenado);
}
if (base.registros == NULL) {
printf("Vetor de registros nao alocado.\n");
}
while (1) {
char op;
if (scanf("%s", &op) != 1) {
break;
} else if (op == 'q') {
break;
} else {
int ra = 0;
if (scanf("%d", &ra) != 1) {
printf("Erro de Leitura do RA\n");
}
if (op == '>') {
imprimir(&base, ra);
} else if (op == '-') {
remover(&base, ra);
} else if (op == '+') {
int telefone;
char nome[100] = "";
if (scanf(" %d %[^\n]", &telefone, nome) != 2) {
printf("Erro de Leitura do telefone e nome.\n");
}
adicionar(&base, ra, telefone, nome);
} else {
printf("Comando %c desconhecido.\n", op);
}
}
while (fgetc(stdin) != '\n')
;
}
liberar_base(&base);
if (base.capacidade != 0) {
printf("A base ainda tem capacidade %d.\n", base.capacidade);
}
if (base.armazenado != 0) {
printf("A base ainda tem %d registros armazenados.\n", base.armazenado);
}
if (base.registros != NULL) {
printf("A base ainda tem um pointeiro de registros.\n");
}
return 0;
}
Arquivo, de minha autoria, com as funções requeridas pela main acima:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int ra, telefone;
char nome[100];
} Aluno;
typedef struct {
int armazenado;
int capacidade;
Aluno *alunos;
} Base;
/* Funcao: criar_base
*
* Inicializa a base ja com a capacidade.
*
* Parametros:
* base: ponteiro para a base
* n: quantidade maxima de alunos
*/
void criar_base(Base *base, int n) {
Aluno *al;
al = (Aluno *) malloc(n * sizeof(Aluno));//Aloca espaço para n Alunos.
(*base).capacidade = n; (*base).armazenado = 0, (*base).alunos = al;//Armazena os valores de inicialização.
printf("Base criada.\n");//Imprime que a base foi criada.
}
/* Funcao: buscar
*
* Parametros:
* base: ponteiro para a base
* ra: numero do RA
*
* Retorno:
* Indice do registro com RA no vetor de alunos
* -1 caso contrario.
*/
int buscar(Base *base, int ra) {
int tam = (*base).armazenado;//Guarda o tamanho numa variável.
for(int i = 0; i<tam; i++)//Percorre o vetor alunos até seu final.
if((*base).alunos[i].ra == ra)//Ao encontrar, retorna o índice i.
return i;
return -1;//Se não retornou i é porque não encontrou aluno. Retorna -1.
}
/* Funcao: imprimir
*
* Parametros:
* base: ponteiro para a base
* ra: numero do RA
*/
void imprimir(Base *base, int ra) {
int pos = buscar(base, ra);//Encontra a posição de aluno.
if(pos == -1){//Se -1, não foi encontrado aluno.
printf("Aluno %d nao encontrado.\n", ra);
return;
}
//Caso contrário, imprime os dados do aluno.
printf("%d - %d - %s\n", (*base).alunos[pos].ra, (*base).alunos[pos].telefone, (*base).alunos[pos].nome);
}
/* Funcoes: adicionar
*
* Inclui um registro sem permitir RAs duplicados.
* O quantidade de alunos deve ser atualizada.
*
* Parametros:
* base: ponteiro para a base
* ra: numero do RA
* telefone: numero do telefone
* nome: string com o nome
*/
void adicionar(Base *base, int ra, int telefone, char *nome) {
int pos = buscar(base, ra), i, adicionado = 0;//Armazena o resultado da busca do aluno em pos.
if(pos == -1){//Se -1, não foi encontrado aluno, logo ele deverá ser adicionado.
if((*base).armazenado >= (*base).capacidade) {//Mas, se estiver cheia a base:
printf("Erro: base cheia.\n");
return;
}
//Caso contrário:
pos = (*base).armazenado, adicionado = 1;
}
//Adiciona ou atualiza os dados ra e telefone na posição pos, que pode ser o índice retornado pela busca ou a última posição do vetor alunos.
(*base).alunos[pos].ra = ra, (*base).alunos[pos].telefone = telefone;
//Adiciona ou atualiza o nome do aluno.
for(i = 0; nome[i] != '\0'; i++)
(*base).alunos[pos].nome[i] = nome[i];
(*base).alunos[pos].nome[i] = '\0';//Adicionar o '\0' ao nome do aluno.
//Incrementa o armazenado, se adicionado, e imprime mensagem do resultado na tela.
if(adicionado)
(*base).armazenado += 1, printf("Adicionado: ");
else
printf("Alterado: ");
printf("%d - %d - %s\n", (*base).alunos[pos].ra, (*base).alunos[pos].telefone, (*base).alunos[pos].nome);
}
/* Funcoes: remover
*
* Remove um registro se o ra estiver presente.
* O quantidade de registro deve ser atualizada.
*
* Parametros:
* base: ponteiro para a base
* ra: numero do RA
*/
void remover(Base *base, int ra) {
int pos = buscar(base, ra), i;//Armazena o resultado da busca do aluno em pos.
if(pos == -1){//Se não encontrado aluno:
printf("Aluno %d nao encontrado.\n", ra);
return;
}
//Caso encontrado, move o próximo aluno do vetor alunos para a posição do aluno anterior.
for(i = pos; i < (*base).armazenado; i++)
(*base).alunos[i] = (*base).alunos[i+1];
//Armazena que há -1 aluno na base.
(*base).armazenado -= 1;
//Imprime resultado da operação.
printf("Aluno %d removido.\n", ra);
}
/* Funcao: liberar_base
*
* Libera a memoria de todos alunos da base.
* Deve deixar a base com capacidade e quantidade armazenada igual a zero
* e o ponteiro para alunos igual a NULL.
*
* Parametros:
* base: ponteiro para a base
*/
void liberar_base(Base *base) {
//Libera o vetor alunos e atualiza capacidade e quantidade armazenada.
free((*base).alunos);
(*base).capacidade = 0, (*base).armazenado = 0, (*base).alunos = NULL;
}