ManipulaÁ„o de registros em arquivos utilizando Ūndices

Publicado por Ewerton Daniel de Lima (ķltima atualizaÁ„o em 11/08/2010)

[ Hits: 9.968 ]

Download indices.rar




Manipulação de registros em arquivos com uso de índice primário e dois índices secundários. Importa e faz um parse do arquivo arqdad.txt. Efetua buscas binárias, implementa uma abordagem de restauração de registros. Utiliza uma estrutura dinâmica para armazenamento e manipulação dos índices em memória principal.

  



Esconder cůdigo-fonte

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


/*
Constantes usadas pela aplicação
*/
char LIMPAR[] = "clear";
char IMPORTACAO[] = "arqdad.txt";
char DADOS[] = "dados.dat";
char HEADER[] = "header.dat";
char IDXNOME[] = "idxnome";
char IDXRED[] = "idxred";


/*
Estrutura b√°sica para armazenamento/tratamento de registros.
Esta estrutura apresenta campos de tamanho fixo baseados
nos tamanhos m√°ximos apresentados nos campos dos registros.
*/
typedef struct cand {
††††char inscricao[8];
††††char nome[33];
††††char nascimento[7];
††††char red[4];
††††char geo[5];
††††char his[5];
††††char bio[5];
††††char mat[5];
††††char port[5];
††††char le[6];
††††char fis[5];
††††char qui[5];
††††char final[7];
††††char clas[4];
††††char obs[4];
} cand;


/*
Estrutura de armazenamento/tratamento de chaves prim√°rias composta por:
 - Valor da chave prim√°ria (key);
 - RRN do registro (rrn);
 - Marcador de item de índice ativo (ativo);
 - Ponteiro para próximo elemento da lista ligada.
*/
typedef struct nodePk {
††††char key[8];
††††int rrn;
††††char ativo;
††††struct nodePk *prox;
††††} nodePk;


/*
Estrutura para armazenamento/tratamento das listas invertidas;
Uma lista invertida é criada para cada nó da lista de chaves secundárias
e mantém ponteiros para os nós da lista de chave primária (acesso 
late binding);
Composta por:
 - Ponteiro para a chave prim√°ria correspondente;
 - Ponteiro para próximo elemento da lista ligada.
*/
typedef struct nodeInvertida {
††††struct nodePk *pk;
††††struct nodeInvertida *prox;
††††} nodeInvertida;


/*
Estrutura para armazenamento/tratamento de chaves secund√°rios.
Cada nó do tipo "nodeSk" cria uma lista invertida. Para isso, mantém:
 - Valor da chave secund√°ria (key);
 - Ponteiros de início e fim da lista invertida correspondente ao nó (first e last);
 - Ponteiro para próximo elemento da lista ligada.
*/
typedef struct nodeSk {
††††char key[33];
††††struct nodeInvertida *first;
††††struct nodeInvertida *last;
††††struct nodeSk *prox;
††††} nodeSk;


//Node inicial e final do índice primário
nodePk *pkFirst, *pkLast;


//Nodes iniciais e finais dos índices secundários
nodeSk *skNomeFirst, *skNomeLast, *skRedFirst, *skRedLast;


//Ponteiros para criação de vetores em tempo de execução para busca binária
nodeSk **vetorSkNome, **vetorSkRed;
nodePk **vetorPk;


//Tamanho dos vetores gerados
int tamanhoVetor, tamSkNome, tamSkRed, tamPk;


/*
Vari√°vel de FLAG: quando valorada em:
 - 0 : Executa rotina de busca sem dar opção de exclusão;
 - 1 : Executa rotina de busca dando opção de exclusão. 
*/
char excluirBusca = 0;


/*
Realiza a criação dos arquivos de dados e cabeçalho
quando os mesmos ainda n√£o existem.
*/
void criarArquivos() {
††††FILE *file;
††††file = fopen(DADOS, "rb");
††††if (!file) {
††††††††file = fopen(DADOS, "wb");
††††††††fclose(file);
††††}
††††file = fopen(HEADER, "rb");
††††if (!file) {
††††††††file = fopen(HEADER, "wb");
††††††††fprintf(file, "i=n");
††††††††fclose(file);
††††}
}


/*
Realiza o trabalho de inserção das chaves primárias nos índices;
Efetua a inserção das chaves já na forma ORDENADA;
Caso já houver o valor de chave primária que se pretende inserir, a função
retornará o endereço do nó em que está alocada a respectiva chave;
Recebe como par√Ęmetro:
 - o valor da chave a ser inserida (key);
 - o rrn (deslocamento) no arquivo de dados (rrn);
 - ponteiro para o início da lista (first);
 - ponteiro para o final do índice (last);

Devolve:
 - Endereço do nó em que está a chave que foi inserida;
*/
nodePk* inserirPk(char *key, int rrn, nodePk **first, nodePk **last) {
††††nodePk *node, *iterador, *ante; //Ponteiros para realiza√ß√£o de percurso
††††node = (nodePk *) malloc(sizeof(nodePk));
††††strcpy(node->key, key);
††††node->rrn = rrn;
††††node->ativo = 1;
††††node->prox = NULL;

††††// Verifica√ß√£o de lista vazia.
††††if (!*first) {
†††††††*first = node;
††††††††*last = node;
††††}
††††else {

†††††††iterador = *first;
†††††††ante = *first;

†††††††while (iterador) {
††††††if (strcmp(iterador->key, key)==0) {
††††††††††††return iterador;
††††††}
††††††if (strcmp(iterador->key, key)>=0) {
†††††††††† break;
††††††}
††††††ante = iterador;
††††††iterador = iterador->prox;
†††††††}

†††††††if (iterador==NULL) {
††††††(*last)->prox = node;
††††††*last = node;
†††††††}
†††††††else if (iterador==ante) {
††††††node->prox = iterador;
††††††*first = node;
†††††††}
†††††††else {
††††††ante->prox = node;
††††††node->prox = iterador;

†††††††}
 }
††return node;
}


/*
Realiza o trabalho de inserção dos elementos da lista invertida;
Efetua a inserção das chaves já na forma ORDENADA;
Recebe como par√Ęmetro:
 - o valor ponteiro para o nó que contém a chave primária correspondente;
 - ponteiro para o início da lista (first);
 - ponteiro para o final do índice (last);
*/
void inserirInvertida(nodePk *pk, nodeInvertida **first, nodeInvertida **last) {
††††nodeInvertida *node, *iterador, *ante;
††††node = (nodeInvertida *) malloc(sizeof(nodeInvertida));
††††node->pk = pk;
††††node->prox = NULL;


††††//Verifica√ß√£o de lista vazia/inser√ß√£o
††††if (!*first) {
†††††††*first = node;
††††††††*last = node;
††††}
††††else {

††††iterador = *first;
††††ante = *first;

††††while (iterador) {
††††††††if (strcmp(iterador->pk->key, pk->key)>=0) {
†††††††††††† break;
††††††††}
††††††††ante = iterador;
††††††††iterador = iterador->prox;
††††}

††††if (iterador==NULL) {
††††††††(*last)->prox = node;
††††††††*last = node;
††††}
††††else if (iterador==ante) {
††††††††node->prox = iterador;
††††††††*first = node;
††††}
††††else {
††††††††ante->prox = node;
††††††††node->prox = iterador;

††††}
 }
}


/*
Realiza o trabalho de inserção das chaves secundárias nos índices;
Efetua a inserção das chaves já na forma ORDENADA;
Recebe como par√Ęmetro:
 - o valor da chave a ser inserida (key);
 - ponteiro para o nó que contém a chave primária correspondente;
 - ponteiro para o início da lista (first);
 - ponteiro para o final do índice (last);
*/
void inserirSk(char *key, nodePk *pk, nodeSk **first, nodeSk **last) {
††††nodeSk *node, *iterador, *ante;
††††node = (nodeSk *) malloc(sizeof(nodeSk));
††††strcpy(node->key, key);
††††node->prox = NULL;

††††node->first = NULL;
††††node->last = NULL;

††††//Verifica√ß√£o de √≠ndice vazio/inser√ß√£o
††††if (!*first) {
†††††††*first = node;
††††††††*last = node;

††††††††//inser√ß√£o de itens na lista invertida
††††††††inserirInvertida(pk, &((*first)->first), &((*first)->last));
††††††††return;
††††}

††††else {

††††iterador = *first;
††††ante = *first;

††††while (iterador) {
††††††††if (strcmp(iterador->key, key)==0) {
††††††††††††††free(node);

††††††††††††††//inser√ß√£o de itens na lista invertida
††††††††††††††inserirInvertida(pk, &(iterador->first), &(iterador->last));
††††††††††††††return;
††††††††}
††††††††if (strcmp(iterador->key, key)>0) {
†††††††††††† break;
††††††††}
††††††††ante = iterador;
††††††††iterador = iterador->prox;
††††}

††††if (iterador==NULL) {
††††††††(*last)->prox = node;
††††††††*last = node;
††††}
††††else if (iterador==ante) {
††††††††node->prox = iterador;
††††††††*first = node;
††††}
††††else {
††††††††ante->prox = node;
††††††††node->prox = iterador;

††††}
†† //inser√ß√£o de itens na lista invertida
††††inserirInvertida(pk, &(node->first), &(node->last));
 }
}


/*
Percorre a lista de índice secundário e retorna seu tamanho
Recebe como par√Ęmetro:
 - ponteiro para o início da lista de índice secundário
*/
int tamIndiceSk(nodeSk *first) {
††††int i = 0;
††††nodeSk *iter = first;
††††while (iter) {
††††††††i++;
††††††††iter = iter->prox;
†††}

††††return i;
}


/*
Cria um vetor a partir de uma lista ligada, percorrendo a lista ligada.
Recebe como par√Ęmetro o ponteiro para o in√≠cio da lista.
*/
nodeSk** listaParaVetor(nodeSk *first) {
††††int i, n;
††††nodeSk **elementos;
††††n = tamIndiceSk(first);
††††elementos = (nodeSk **) malloc(sizeof(nodeSk *)*n);

††††for (i=0; i<n; i++) {
††††††††elementos[i] = first;
††††††††first = first->prox;
††††}
††††tamanhoVetor = n;
††††return elementos;
}


/*
Percorre a lista de índice primário e retorna seu tamanho
Recebe como par√Ęmetro:
 - ponteiro para o início da lista de índice primário
*/
int tamIndicePk(nodePk *first) {
††††int i = 0;
††††nodePk *iter = first;
††††while (iter) {
††††††††if (iter->ativo) {
††††††††i++;
††††††††}
††††††††iter = iter->prox;
†††}
††††return i;
}


/*
Cria um vetor a partir de uma lista ligada, percorrendo a lista ligada.
Recebe como par√Ęmetro o ponteiro para o in√≠cio da lista.
*/
nodePk** listaParaVetorPk(nodePk *first) {
††††int i, n;
††††nodePk **elementos;
††††n = tamIndicePk(first);
††††elementos = (nodePk **) malloc(sizeof(nodePk *)*n);

††††for (i=0; i<n; i++) {
††††††††while (!(first->ativo)) {
††††††††first = first->prox;
††††††††}
††††††††elementos[i] = first;
††††††††first = first->prox;
††††}
††††tamanhoVetor = n;
††††return elementos;


}


/*
Atualiza tamanhos dos índices e recria os vetores.
*/
void atualizaVetores() {
†† free(vetorSkNome);
†† free(vetorSkRed);
†† free(vetorPk);
†† vetorPk = listaParaVetorPk(pkFirst);
†† tamPk = tamanhoVetor;
†† vetorSkNome = listaParaVetor(skNomeFirst);
†† tamSkNome = tamanhoVetor;
†† vetorSkRed = listaParaVetor(skRedFirst);
†† tamSkRed = tamanhoVetor;
}


/*
Recebe uma string e um tamanho.
Atribui, at√© o limite dado como par√Ęmetro, espa√ßos, encerrando com o caracter {FONTE}.
*/
void completaEspacos(char *str, int tamanho) {
†††† int i=0, x=0;
†††† if (str[i]==0) return;
†††† for (i=0; i<tamanho; i++) {
††††††††††x = i;
††††††††††if (str[i]==0) break;
†††† }
†††† for (i=x; i<tamanho; i++) {
†††††††† str[i] = ' ';
†††† }
†††† str[tamanho-1] = 0;
}


/*
Permite ao usu√°rio adicionar um novo item ao arquivo de dados;
Os registros adicionados são incluídos também nos índices primário e secundário;
*/
void inserir() {
††††cand c;
††††int rrn, tamCampo;
††††system(LIMPAR);
††††getchar();
††††printf("INSERIR INFORMA√á√ēES DE NOVO CANDIDATO\n");

††††do {
††††printf("\nN√ļmero de inscri√ß√£o††(m√°x:7): ");
††††gets(c.inscricao);
††††tamCampo = strlen(c.inscricao);
††††} while (tamCampo>7);
††††completaEspacos(c.inscricao, 8);

††††do {
††††printf("\nNome (m√°x:32): ");
††††gets(c.nome);
††††tamCampo = strlen(c.nome);
††††} while (tamCampo>32);

††††do {
††††printf("\nNascimento††(m√°x:6): ");
††††gets(c.nascimento);
††††tamCampo = strlen(c.nascimento);
††††} while (tamCampo>6);
††††completaEspacos(c.nascimento, 7);

††††do {
††††printf("\nReda√ß√£o (m√°x:3): ");
††††gets(c.red);
††††tamCampo = strlen(c.red);
††††} while (tamCampo>3);
††††completaEspacos(c.red, 4);

††††do {
††††printf("\nGeografia (m√°x:4): ");
††††gets(c.geo);
††††tamCampo = strlen(c.geo);
††††} while (tamCampo>4);
††††completaEspacos(c.geo, 5);

††††do {
††††printf("\nHist√≥ria (m√°x:4): ");
††††gets(c.his);
††††tamCampo = strlen(c.his);
††††} while (tamCampo>4);
††††completaEspacos(c.his, 5);

††††do {
††††printf("\nBiologia (m√°x:4): ");
††††gets(c.bio);
††††tamCampo = strlen(c.bio);
††††} while (tamCampo>4);
††††completaEspacos(c.bio, 5);

††††do {
††††printf("\nMatem√°tica (m√°x:4): ");
††††gets(c.mat);
††††tamCampo = strlen(c.mat);
††††} while (tamCampo>4);
††††completaEspacos(c.mat, 5);

††††do {
††††printf("\nPortugu√™s (m√°x:4): ");
††††gets(c.port);
††††tamCampo = strlen(c.port);
††††} while (tamCampo>4);
††††completaEspacos(c.port, 5);

††††do {
††††printf("\nL√≠ngua Estrangeira (m√°x:5): ");
††††gets(c.le);
††††tamCampo = strlen(c.le);
††††} while (tamCampo>5);
††††completaEspacos(c.le, 6);

††††do {
††††printf("\nF√≠sica (m√°x:4): ");
††††gets(c.fis);
††††tamCampo = strlen(c.fis);
††††} while (tamCampo>4);
††††completaEspacos(c.fis, 5);

††††do {
††††printf("\nQu√≠mica (m√°x:4): ");
††††gets(c.qui);
††††tamCampo = strlen(c.qui);
††††} while (tamCampo>4);
††††completaEspacos(c.qui, 5);

††††do {
††††printf("\nEscore Final (m√°x:6): ");
††††gets(c.final);
††††tamCampo = strlen(c.final);
††††} while (tamCampo>6);
††††completaEspacos(c.final, 7);

††††do {
††††printf("\nClassifica√ß√£o (m√°x:3): ");
††††gets(c.clas);
††††tamCampo = strlen(c.clas);
††††} while (tamCampo>3);
††††completaEspacos(c.clas, 4);

††††do {
††††printf("\nObserva√ß√£o (m√°x:3): ");
††††gets(c.obs);
††††tamCampo = strlen(c.obs);
††††} while (tamCampo>3);
††††completaEspacos(c.obs, 4);

††††FILE *fd;
††††fd = fopen(DADOS, "a");

††††rrn = ftell(fd);


††††fprintf(fd, "|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|#",
††††c.inscricao, c.nome, c.nascimento, c.red, c.geo, c.his, c.bio, c.mat, c.port, c.le, c.fis, c.qui, c.final, c.clas, c.obs);

††††//Inclus√£o de registros nos √≠ndices prim√°rio e secund√°rio.
††††nodePk *p;
††††p = inserirPk(c.inscricao, rrn, &pkFirst, &pkLast);
††††inserirSk(c.nome, p, &skNomeFirst, &skNomeLast);
††††inserirSk(c.red, p, &skRedFirst, &skRedLast);

††††fclose(fd);

}


/*
Percorre o arquivo de dados com base no rrn e adiciona
uma marca de exclusão (*), além de desativar o respectivo nó;
Recebe como par√Ęmetro:
 - o ponteiro para o nó do registro a ser excluído;
*/
void excluir(nodePk *node) {
††††node->ativo = 0;
††††FILE *file;
††††file = fopen(DADOS, "r+b");
††††fseek(file, node->rrn, SEEK_SET);
††††fputc('*', file);
††††fclose(file);
}


/*
Exibe na tela o registro contido no arquivo de dados, indicado pelo RRN;
*/
void imprimirRegistro(int rrn) {
††††char registro[150], c;
††††int x = 0;
††††FILE *file;
††††file = fopen(DADOS, "rb");
††††fseek(file, rrn+1, SEEK_SET);
††††while ((c=fgetc(file))!='#') {
†††††† registro[x] = c;
†††††† x++;
††††}
††††registro[x] = 0;

††††printf("\n\nN√ļmero de Inscri√ß√£o: %s", strtok(registro, "|*"));
††††printf("\nNome: %s", strtok(NULL, "|*"));
††††printf("\nData de nascimento: %s", strtok(NULL, "|*"));
††††printf("\n:::::::::::::::::::::::::::NOTAS::::::::::::::\
:::::::::::::\nRedação: %s; ", strtok(NULL, "|*"));
††††printf("Geografia: %s; ", strtok(NULL, "|*"));
††††printf("Hist√≥ria: %s; ", strtok(NULL, "|*"));
††††printf("\nBiologia: %s; ", strtok(NULL, "|*"));
††††printf("Matem√°tica: %s; ", strtok(NULL, "|*"));
††††printf("Portugu√™s: %s; ", strtok(NULL, "|*"));
††††printf("\nL√≠ngua Estrangeira: %s; ", strtok(NULL, "|*"));
††††printf("F√≠sica: %s; ", strtok(NULL, "|*"));
††††printf("Qu√≠mica: %s; ", strtok(NULL, "|*"));
††††printf("\n:::::::::::::::::::::::::RESULTADOS:::::::::::\
:::::::::::::\nEscore Final: %s; ", strtok(NULL, "|*"));
††††printf("Classifica√ß√£o: %s; ", strtok(NULL, "|*"));
††††printf("Observa√ß√£o: %s; \n", strtok(NULL, "|*"));
††††printf("-----------------------------------------------------------\n");

††††fclose(file);
}


/*
Exibe para o usuário todos os itens dos índices secundários
*/
void mostrarSk(nodeSk *first) {
††††getchar();
††††nodeInvertida *inv;
††††while (first) {

††††††††inv = first->first;
††††††††while(inv) {
††††††††††††if (inv->pk->ativo) {
††††††††††††imprimirRegistro(inv->pk->rrn);


††††††††††††printf("Pressione ENTER para pr√≥ximo registro (ESC + ENTER para voltar)...");
††††††††††††if (getchar()==27) return;
††††††††††††}
††††††††††††inv = inv->prox;
††††††††}

††††††††first = first->prox;

††††††††}

}


/*
Exibe para o usuário todos os itens dos índices primários
*/
void mostrarPk(nodePk *first) {
††††getchar();

††††while (first) {
††††††††if (first->ativo) {
††††††††imprimirRegistro(first->rrn);
††††††††printf("Pressione ENTER para pr√≥ximo registro (ESC + ENTER para voltar)...");
††††††††if (getchar()==27) return;
††††††††}
††††††††first = first->prox;
††††††††}

}


/*
Busca no vetor construído a partir do índice primário o valor informado;
Usa o método de busca binária;
Recebe como par√Ęmetro:
 - a chave a ser pesquisada;
 - vetor onde deve ser pesquisado;
 - o tamanho do vetor onde deve ser pesquisado;
*/
void buscaPk(char *elemento, nodePk **vetor, int tamVetor) {
†† int inf = 0, sup = tamVetor-1, x, encontrado = 0;

†† while (inf <= sup) {
††††††x = (inf+sup)/2;
††††††if (strcmp((vetor[x])->key, elemento)==0) {
††††††††††encontrado = 1;
††††††††††break;
††††††}
††††††else if (strcmp((vetor[x])->key, elemento)<0) {
††††††††††inf = x + 1;
††††††}

††††††else {
†††††††††† sup = x - 1;
††††††}

†† }
††system(LIMPAR);
††printf("RESULTADOS DA BUSCA POR: \"%s\"\n\n", elemento);
††if (encontrado) {
††††††char opcao;
††††††char *op = &opcao;
††††††getchar();
††††††if ((vetor[x])->ativo) {

††††††††††††opcao = 'N';
††††††††††††imprimirRegistro((vetor[x])->rrn);

††††††††††††if (excluirBusca) {
††††††††††††printf("\nDESEJA EXCLUIR ESSE REGISTRO? (S/N)\n");
††††††††††††gets(op);
††††††††††††if (opcao == 'S' || opcao == 's') {
††††††††††††††††excluir((vetor[x]));
††††††††††††††††atualizaVetores();
††††††††††††}
††††††††††††}
}
††}

††else {
†††† printf("N√£o foi encontrado o item");
††††}

}


/*
Busca no vetor construído a partir de um dos índices
secund√°rios o valor informado;
Usa o método de busca binária;
Recebe como par√Ęmetro:
 - a chave a ser pesquisada;
 - vetor onde deve ser pesquisado;
 - o tamanho do vetor onde deve ser pesquisado;
*/
void buscaBinaria(char *elemento, nodeSk **vetor, int tamVetor) {
†† int inf = 0, sup = tamVetor-1, x, encontrado = 0;

†† while (inf <= sup) {
††††††x = (inf+sup)/2;
††††††if (strcmp((vetor[x])->key, elemento)==0) {
††††††††††encontrado = 1;
††††††††††break;
††††††}
††††††else if (strcmp((vetor[x])->key, elemento)<0) {
††††††††††inf = x + 1;
††††††}

††††††else {
††††††††††sup = x - 1;
††††††}

†† }

††system(LIMPAR);
††printf("RESULTADOS DA BUSCA POR: \"%s\"\n", elemento);
††if (encontrado) {
†††† nodeInvertida *inv;
†††† inv = (vetor[x])->first;
††††††††char opcao;
††††††††char *op = &opcao;

††††††††// Percurso da lista e op√ß√£o para exclus√£o de registro
††††††††while(inv) {
††††††††††††opcao = 'N';
††††††††††††if (inv->pk->ativo) {
††††††††††††imprimirRegistro(inv->pk->rrn);
††††††††††††if (excluirBusca) {
††††††††††††printf("\nDESEJA EXCLUIR ESSE REGISTRO? (S/N)\n");
††††††††††††gets(op);
††††††††††††if (opcao == 'S' || opcao == 's') {
††††††††††††††††excluir(inv->pk);
††††††††††††††††atualizaVetores();
††††††††††††}
††††††††††††}

††††††††††††printf("Pressione ENTER para pr√≥ximo registro (ESC + ENTER para voltar)...");
††††††††††††if (getchar()==27) return;

††††††††††††}
††††††††††††inv = inv->prox;
††††††††}

}

††else {
†††† printf("N√£o foi encontrado o item");
†† }

}


/*
MENU DE PESQUISA
*/
void menuPesquisar() {
††††char opcao = ' ';
††††char valor[33];
††††while (opcao!='4') {
††††getchar();
††††system(LIMPAR);
††††if (excluirBusca) {
††††printf("EXCLUS√ÉO DE REGISTROS\n");
††††}
††††printf("PESQUISAR REGISTROS POR: \n\n");
††††printf("1. N√ļmero de Inscri√ß√£o\n");
††††printf("2. Nome\n");
††††printf("3. Nota da Reda√ß√£o\n");
††††printf("4. Voltar\n");
††††printf("\nEscolha uma op√ß√£o: ");

††††opcao = getchar();

††††if (opcao=='1') {
††††††††printf("\nEntre com a chave prim√°ria: ");
††††††††scanf("%s", valor);
††††††††completaEspacos(valor, 8);
††††††††buscaPk(valor, vetorPk, tamPk);
††††††††printf("\nFim de busca, pressione ENTER para continuar...\n");
††††}
††††if (opcao=='2') {
††††††††getchar();
††††††††printf("\nEntre com o nome: ");
††††††††gets(valor);
††††††††buscaBinaria(valor, vetorSkNome, tamSkNome);
††††††††printf("\nFim de busca, pressione ENTER para continuar...\n");
††††}
††††if (opcao=='3') {
††††††††printf("\nEntre com a nota de reda√ß√£o: ");
††††††††scanf("%s", valor);
††††††††completaEspacos(valor, 4);
††††††††getchar();
††††††††buscaBinaria(valor, vetorSkRed, tamSkRed);
††††††††printf("\nFim de busca, pressione ENTER para continuar...\n");

††††}

††††}
}


/*
Desaloca todos os dados utilizados pelos índices mantidos em memória
*/
void limparIndices() {

††††nodeInvertida *inv, *anteInv;
††††nodeSk *sk, *anteSk;

††††sk = skNomeFirst;

††††while (sk) {
††††††††inv = sk->first;
††††††††anteInv = NULL;
††††††††while (inv) {
††††††††††††anteInv = inv;
††††††††††††inv = inv->prox;
††††††††††††free(anteInv->pk);
††††††††††††free(anteInv);
††††††††}
††††††††anteSk = sk;
††††††††sk = sk->prox;
††††††††free(anteSk);
††††}

††††sk = skRedFirst;

††††while (sk) {
††††††††inv = sk->first;
††††††††anteInv = NULL;
††††††††while (inv) {
††††††††††††anteInv = inv;
††††††††††††inv = inv->prox;
††††††††††††free(anteInv);
††††††††}
††††††††anteSk = sk;
††††††††sk = sk->prox;
††††††††free(anteSk);
††††}

††††pkFirst = NULL;
††††skNomeFirst = NULL;
††††skRedFirst = NULL;

}


/*
Efetua a gravação das listas de índices primário e secundário em arquivos
*/
void salvarIndices() {

††††nodeInvertida *inv;
††††nodePk *pk;
††††nodeSk *skn, *skr;
††††FILE *fn, *fr;
††††fn = fopen(IDXNOME, "wb");
††††fr = fopen(IDXRED, "wb");

††††skn = skNomeFirst;


††††while (skn) {
††††††††inv = skn->first;
††††††††while (inv) {
††††††††††††if (inv->pk->ativo) {
††††††††††††fprintf(fn, "%s|%s|%d|\n", inv->pk->key, skn->key, inv->pk->rrn);
††††††††††††}
††††††††††††inv = inv->prox;
††††††††}
††††††††skn = skn->prox;
††††}

††††skr = skRedFirst;

††††while (skr) {
††††††††inv = skr->first;
††††††††while (inv) {
††††††††††††if (inv->pk->ativo) {
††††††††††††fprintf(fr, "%s|%s|%d|\n", inv->pk->key, skr->key, inv->pk->rrn);
††††††††††††}
††††††††††††inv = inv->prox;
††††††††}
††††††††skr = skr->prox;
††††}

††††fclose(fn);
††††fclose(fr);
}


/*
Caso os índices sejam apagados, reconstroi os mesmos;
O par√Ęmetro "recupera" pode ser valorado como:
 - 0 : efetua reconstrução sem recuperar registro excluídos
 - 1 : efetua reconstrução recuperando registro excluídos
*/
void reconstruirIndices(int recupera) {
††††limparIndices();
††††nodePk *p;
††††char registro[150], c, *pk, *nome, *red;
††††int x, rrn = 0;
††††FILE *file;
††††file = fopen(DADOS, "rb");
††††if (!file) {
††††††††printf("\nN√£o foi poss√≠vel abrir o arquivo de dados...");
††††††††return;
††††}

††††while (1) {
††††††††x = 0;
††††while (((c=fgetc(file))!='#')) {
††††††††if (feof(file)) {
††††††††††††fclose(file);
††††††††††††salvarIndices();
††††††††††††printf("\nOs √≠ndices foram reconstru√≠dos com sucesso...");
††††††††††††getchar();
††††††††††††return;
††††††††††††}
†††††† registro[x] = c;
†††††† x++;
††††}
††††registro[x] = 0;
††††if (recupera==1||(recupera==0 && registro[0]!='*')) {
††††pk = strtok(registro, "|*");
††††nome = strtok(NULL, "|*");
††††strtok(NULL, "|*");
††††red = strtok(NULL, "|*");

††††completaEspacos(red, 4);
††††p = inserirPk(pk, rrn, &pkFirst, &pkLast);
††††inserirSk(nome, p, &skNomeFirst, &skNomeLast);
††††inserirSk(red, p, &skRedFirst, &skRedLast);
}
††††rrn = ftell(file);
††††
†††††† }
}


/*
Carrega para memória todos os índices gravados em arquivo;
*/
void carregarIndices() {
††††limparIndices();
††††FILE *nome, *red;
††††nome = fopen(IDXNOME, "rb");
††††red = fopen(IDXRED, "rb");
††††if (nome&&red) {
††††char linha[100], *key, *pk, *rrn;
††††nodePk *p;

††††while (fgets(linha, 100, nome)) {
††††††††pk = strtok(linha, "|*");
††††††††key = strtok(NULL, "|*");
††††††††rrn = strtok(NULL, "|*");
††††††††p = inserirPk(pk, atoi(rrn), &pkFirst, &pkLast);
††††††††inserirSk(key, p, &skNomeFirst, &skNomeLast);

††††}

††††while (fgets(linha, 100, red)) {
††††††††pk = strtok(linha, "|*");
††††††††key = strtok(NULL, "|*");
††††††††rrn = strtok(NULL, "|*");
††††††††p = inserirPk(pk, atoi(rrn), &pkFirst, &pkLast);
††††††††inserirSk(key, p, &skRedFirst, &skRedLast);
††††}

††††}

††††else {
††††††††printf("\nN√£o foi poss√≠vel carregar os √≠ndices, pressione ENTER\
 para iniciar a reconstrução dos índices...");
††††††††getchar();
††††††††reconstruirIndices(0);
††††}

}


/*
Realiza a abertura e importação do arquivo "arqdad.txt"
*/
void importar() {
††††FILE *file;
††††file = fopen(HEADER, "rb");
††††char l[4];
††††fscanf(file, "%s", l);
††††fclose(file);
††††if (l[2] == 's') {
††††††††printf("\n\nO arquivo arqdad.txt j√° foi importado.");
††††††††getchar();
††††††††return;
††††}
††††cand candidato;
††††char linha[150];
††††int rrn, i, x=0;
††††FILE *saida, *fd;
††††fd = fopen(IMPORTACAO, "rb");
††††saida = fopen(DADOS, "ab");

††††if (!fd) {
††††††††printf("ARQUIVO DE IMPORTA√á√ÉO N√ÉO ENCONTRADO...");
††††††††getchar();
††††††††return;
††††}
††††for (i=0; i<7; i++) {
††††††††fgets(linha, 150, fd);
††††††††}
††††rrn = 0;
††††while (fgets(linha, 150, fd)) {

††††††††fseek(saida, 0, SEEK_END);
††††††††rrn = ftell(saida);

††††††††for (i=1; i<8; i++) {
††††††††††††candidato.inscricao[x]=linha[i];
††††††††††††x++;
††††††††††††}
††††††††candidato.inscricao[x] = 0;
††††††††x = 0;
††††††††fprintf(saida, "|%s|", candidato.inscricao);

††††††††for (i=10; i<43; i++) {
††††††††††††if ((linha[i]==' ')&&(linha[i+1]==' ')) break;
††††††††††††candidato.nome[x]=linha[i];
††††††††††††x++;
††††††††††††}
††††††††candidato.nome[x] = 0;
††††††††x = 0;
††††††††fprintf(saida, "%s|", candidato.nome);

††††††††for (i=43; i<49; i++) {
††††††††††††candidato.nascimento[x]=linha[i];
††††††††††††x++;
††††††††††††}
††††††††candidato.nascimento[x] = 0;
††††††††x = 0;
††††††††fprintf(saida, "%s|", candidato.nascimento);

††††††††for (i=52; i<56; i++) {
††††††††††††candidato.red[x]=linha[i];
††††††††††††x++;
††††††††††††}
††††††††candidato.red[x] = 0;
††††††††x = 0;
††††††††fprintf(saida, "%s|", candidato.red);

††††††††for (i=57; i<61; i++) {
††††††††††††candidato.geo[x]=linha[i];
††††††††††††x++;
††††††††††††}
††††††††candidato.geo[x] = 0;
††††††††x = 0;
††††††††fprintf(saida, "%s|", candidato.geo);

††††††††for (i=62; i<67; i++) {
††††††††††††candidato.his[x]=linha[i];
††††††††††††x++;
††††††††††††}
††††††††candidato.his[x] = 0;
††††††††x = 0;
††††††††fprintf(saida, "%s|", candidato.his);

††††††††for (i=68; i<73; i++) {
††††††††††††candidato.bio[x]=linha[i];
††††††††††††x++;
††††††††††††}
††††††††candidato.bio[x] = 0;
††††††††x = 0;
††††††††fprintf(saida, "%s|", candidato.bio);

††††††††for (i=73; i<78; i++) {
††††††††††††candidato.mat[x]=linha[i];
††††††††††††x++;
††††††††††††}
††††††††candidato.mat[x] = 0;
††††††††x = 0;
††††††††fprintf(saida, "%s|", candidato.mat);

††††††††for (i=80; i<85; i++) {
††††††††††††candidato.port[x]=linha[i];
††††††††††††x++;
††††††††††††}
††††††††candidato.port[x] = 0;
††††††††x = 0;
††††††††fprintf(saida, "%s|", candidato.port);

††††††††for (i=85; i<91; i++) {
††††††††††††candidato.le[x]=linha[i];
††††††††††††x++;
††††††††††††}
††††††††candidato.le[x] = 0;
††††††††x = 0;
††††††††fprintf(saida, "%s|", candidato.le);

††††††††for (i=92; i<97; i++) {
††††††††††††candidato.fis[x]=linha[i];
††††††††††††x++;
††††††††††††}
††††††††candidato.fis[x] = 0;
††††††††x = 0;
††††††††fprintf(saida, "%s|", candidato.fis);

††††††††for (i=97; i<102; i++) {
††††††††††††candidato.qui[x]=linha[i];
††††††††††††x++;
††††††††††††}
††††††††candidato.qui[x] = 0;
††††††††x = 0;
††††††††fprintf(saida, "%s|", candidato.qui);

††††††††for (i=103; i<109; i++) {
††††††††††††candidato.final[x]=linha[i];
††††††††††††x++;
††††††††††††}
††††††††candidato.final[x] = 0;
††††††††x = 0;
††††††††fprintf(saida, "%s|", candidato.final);

††††††††for (i=112; i<116; i++) {
††††††††††††candidato.clas[x]=linha[i];
††††††††††††x++;
††††††††††††}
††††††††candidato.clas[x] = 0;
††††††††x = 0;
††††††††fprintf(saida, "%s|", candidato.clas);

††††††††for (i=117; i<120; i++) {
††††††††††††candidato.obs[x]=linha[i];
††††††††††††x++;
††††††††††††}
††††††††candidato.obs[x] = 0;
††††††††x = 0;
††††††††fprintf(saida, "%s|#", candidato.obs);

††††candidato.inscricao[7] = 0;
††††candidato.nome[32] = 0;
††††candidato.red[3] = 0;

††††nodePk *p;
††††p = inserirPk(candidato.inscricao, rrn, &pkFirst, &pkLast);
††††inserirSk(candidato.nome, p, &skNomeFirst, &skNomeLast);
††††inserirSk(candidato.red, p, &skRedFirst, &skRedLast);


††††††}
††††file = fopen(HEADER, "wb");
††††l[2] = 's';
††††fprintf(file, "%s", l);
††††fclose(file);
}


/*
Cria um novo arquivo de dados, excluindo definitivamente os
registros outrora somente removidos logicamente.
*/
void removerDefinitivo() {
††††int x;
††††char c, registro[150];
††††FILE *file, *tmp;
††††file = fopen(DADOS, "rb");
††††tmp = fopen("tmp", "wb");
††††if (!file) {
††††††††printf("\nN√£o foi poss√≠vel abrir o arquivo de dados...");
††††††††return;
††††}

††††while (1) {
††††††††x = 0;
††††while (((c=fgetc(file))!='#')) {
††††††††if (feof(file)) {
††††††††††††fclose(file);
††††††††††††fclose(tmp);
††††††††††††remove(DADOS);
††††††††††††rename("tmp", DADOS);
††††††††††††reconstruirIndices(1);
††††††††††††printf("\nTodos os registros removidos logicamente foram definitivamente removidos...");
††††††††††††return;
††††††††††††}
†††††† registro[x] = c;
†††††† x++;
††††}
††††registro[x] = '#';
††††registro[x+1] = 0;

††††if (registro[0]!='*') {
†††† fprintf(tmp, "%s", registro);
†††}

†††††† }†† 

}


/*
MENU DE LISTAGEM DE REGISTROS
*/
void menuListar() {
†† char opcao = ' ';
††††char valor[33];
††††getchar();
††††while (opcao!='4') {
††††system(LIMPAR);

††††printf("LISTAR REGISTROS POR: \n\n");
††††printf("1. N√ļmero de Inscri√ß√£o\n");
††††printf("2. Nome\n");
††††printf("3. Nota da Reda√ß√£o\n");
††††printf("4. Voltar\n");
††††printf("\nEscolha uma op√ß√£o: ");

††††scanf("%c", &opcao);

††††if (opcao=='1') {
††††††††mostrarPk(pkFirst);
††††}
††††if (opcao=='2') {
††††††††mostrarSk(skNomeFirst);

††††}
††††if (opcao=='3') {
††††††††mostrarSk(skRedFirst);

††††}


††††}
}


/*
MENU DE INSERCAO DE REGISTROS
*/
void menuInserir() {

††††char opcao = ' ';
††††getchar();
††††while (opcao!='2') {
††††system(LIMPAR);

††††printf("INSERIR NOVO REGISTRO\n");
††††printf("1. Iniciar inser√ß√£o de dados\n");
††††printf("2. Voltar\n");
††††printf("\nEscolha uma op√ß√£o: ");

††††scanf("%c", &opcao);

††††if (opcao=='1') {
††††††††inserir();
††††}
††††}
}


/*
MENU PRINCIPAL
*/
int menuPrincipal() {
††††char opcao[] = "††";
††††system(LIMPAR);
††††printf("Pressione ENTER...");
††††while (opcao[0] != '1' && (opcao[1] != '1' || opcao[1] != '0')) {
††††††††getchar();
††††††††system(LIMPAR);

††††††††printf("MANIPULA√á√ÉO DE ARQUIVOS DE DADOS COM USO DE √ćNDICES");
††††††††printf("\n\n1. Inserir");
††††††††printf("\n2. Excluir");
††††††††printf("\n3. Listar");
††††††††printf("\n4. Buscar");
††††††††printf("\n5. Importar arquivo \"arqdad.txt\"");
††††††††printf("\n6. Restaurar registros removidos logicamente");
††††††††printf("\n7. Reconstruir √≠ndices");
††††††††printf("\n8. Remover registros definitivamente");
††††††††printf("\n9. Salvar altera√ß√Ķes");
††††††††printf("\n10. Cancelar altera√ß√Ķes e sair");
††††††††printf("\n11. Salvar altera√ß√Ķes e sair");
††††††††printf("\n\nEscolha uma op√ß√£o v√°lida: ");

††††††††scanf("%s", opcao);

††††††††if (opcao[0] == '1' && opcao[1] == '0') {
††††††††††††return 0;
††††††††}

††††††††if (opcao[0] == '1' && opcao[1] == '1') {
††††††††††††return 1;
††††††††}

††††††††if (opcao[0] == '1') {
††††††††††††menuInserir();
††††††††}

††††††††if (opcao[0] == '2') {
††††††††††††atualizaVetores();
††††††††††††excluirBusca = 1;
††††††††††††menuPesquisar();
††††††††}

††††††††if (opcao[0] == '3') {
††††††††††††excluirBusca = 0;
††††††††††††menuListar();
††††††††}

††††††††if (opcao[0] == '4') {
††††††††††††atualizaVetores();
†††††††excluirBusca = 0;
††††††††††††menuPesquisar();
††††††††}

††††††††if (opcao[0] == '5') {
††††††††††††importar();
††††††††}

††††††††if (opcao[0] == '6') {
††††††††††††limparIndices();
††††††††††††reconstruirIndices(1);
††††††††††††salvarIndices();
††††††††††††printf("\n\nOs registros exclu√≠dos foram restaurados!");

††††††††}

††††††††if (opcao[0] == '7') {
††††††††††††reconstruirIndices(0);
††††††††}

††††††††if (opcao[0] == '8') {
††††††††††††removerDefinitivo();
††††††††}

††††††††if (opcao[0] == '9') {
††††††††††††salvarIndices();
††††††††††††printf("\n\nAs altera√ß√Ķes foram gravadas nos arquivos de √≠ndices...");
††††††††††††getchar();
††††††††}
††††}
}


/*
Programa principal
*/
int main() {

//Verifica se os arquivos j√° existem e os cria, caso negativo;
criarArquivos();

//Carrega os índices do arquivo para a memória;
carregarIndices();

//Salva índices se for a opção escolhida pelo usuário;
if (menuPrincipal()) {
††††salvarIndices();
†† }
}

Scripts recomendados

Cadastro de arquivo usando ncurses como menu

Programa CONSULTA/ PESQUISA/ ADICIONA/ EXCLUI registros em arquivos

Transformando uma sequencia de binŠrio em executŠvel

leitura/escrita de dados/estruturas em arquivo

FaÁa um programa em c++ gere um arquivo e depois leia usando um gerador de numeros do tipo s


  

ComentŠrios

Nenhum comentŠrio foi encontrado.


Contribuir com comentŠrio




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner
Linux banner
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts