Manipulação de registros em arquivos utilizando índices

Publicado por Perfil removido (última atualização em 11/08/2010)

[ Hits: 11.767 ]

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

Xml2Txt

Contando a quantidade de palavras de um arquivo texto

Organizador de filmes para o IMDB

Cadastro de arquivo usando ncurses como menu

Listar arquivos e diretórios com suas propriedades


  

Comentários

Nenhum comentário foi encontrado.


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts