Advertisement
Guest User

Untitled

a guest
May 27th, 2018
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 32.70 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. /****************************ESTRUTURAS UTILIZADAS********************************/
  5. typedef struct Lista
  6. {
  7.     char chave_primaria[31];
  8.   char curso[3];
  9.   int op;
  10.   int matric;
  11.   char nome[43];
  12.   char turma;
  13.   int num_arq;  // NUMERO DO ARQUIVO 1 OU 2
  14.   int posicao; // BYTEOFFSET
  15.     struct Lista *prox;
  16.   struct Lista *ant;
  17. } Lista;
  18.  
  19. typedef struct Aponta
  20. {
  21.     Lista *inicio;
  22.     Lista *fim;
  23.   int tamanho;
  24. } Aponta;
  25.  
  26. typedef struct ListaInvertida
  27. {
  28.   int id;
  29.   char chave_primaria[31];
  30.   char curso[3];
  31.   struct ListaInvertida* prox;
  32. }ListaInvertida;
  33.  
  34. typedef struct Pilha
  35. {
  36.     int qtd;
  37.   int arq;
  38.     int nrr[20];
  39. }Pilha;
  40. /**********************************************************************************/
  41.  
  42. /******************************DECLARACOES DE FUNCOES******************************/
  43. /* FUNCOES PARA CRIACAO E MANIPULACAO DA PED (PILHA DE ESPACOS DISPONIVEIS) */
  44. Pilha * CriaPilha();
  45. void InserePilha(Pilha *pi, int p, int arq);
  46. int RemovePilha(Pilha *pi);
  47. /****************************************************************************/
  48. /* FUNCÕES PARA INTERAÇÃO COM USUÁRIO */
  49. int menu();
  50. void escolha(int opcao, Aponta *lista1, Aponta *lista2, Aponta *lista3, ListaInvertida **listainvertida1, ListaInvertida **listainvertida2, Pilha *PED);
  51. /**************************************/
  52. /* FUNCOES PARA CRIACAO E MANIPULACAO DA LISTA DUPLAMENTE ENCADEADA DOS REGISTROS */
  53. void InsereOrdenado(Aponta *lista, int matricula, char *nome, char *curso, char turma, int op, int num_arq, int posicao, char *chave_primaria);
  54. void MostraLista(Aponta *lista,int arquivo);
  55. Aponta *CriaLista();
  56. Lista *AlocaLista(int matricula, char *nome, char* curso, char turma, int op, int num_arq, int posicao, char *chave_primaria);
  57. void RetiraFim(Aponta *lista);
  58. void RetiraInicio(Aponta *lista);
  59. void free_node(Lista **n);
  60. int vazia (Aponta *lista);
  61. void libera(Aponta *lista);
  62. Lista *RetornaNo(Aponta *lista,int indice);
  63. /**********************************************************************************/
  64. /* FUNCOES PARA CRIACAO E MANIPULACAO DOS INDICES PRIMARIOS E SECUNDARIOS */
  65. void CriaIndices(Aponta *lista,int opcao);
  66. void ManipulaString(char *string, int desloca, int num_arq, Aponta *lista);
  67. void IncluiRegistroLista(Aponta *lista,int arquivo,Pilha *PED);
  68. void AtualizaIndices(Aponta *lista, int num_arq);
  69. void Atualizacao(Aponta *lista, int indice, int num_arq);
  70. void EscreveIndicesPrimarios(Aponta *lista, int num_arq);
  71. void EscreveIndicesSecundarios(Aponta *lista, int num_arq);
  72. void MostrarChavesPrimarias(Aponta *lista,int arquivo);
  73. void MostrarChavesSecundarias(Aponta *lista,int arquivo);
  74. void Exclusao(Aponta* lista, int arquivo, int indice, Pilha *PED);
  75. void RemoveIndice(Aponta *lista, int indice);
  76. /**************************************************************************/
  77. /* FUNCOES PARA JUNCAO(MERGE) DOS INDICES DOS REGISTROS DA LISTA 1 E 2 ORDENADOS */
  78. void CriaArquivoMerge(Aponta *lista);
  79. Lista *CombinaListas(Lista *esquerda, Lista *direita);
  80. void RemoveIguais(Aponta *lista);
  81. /*********************************************************************************/
  82. /*FUNCOES UTILIZADAS PARA CRIACAO E MANIPULACAO DA LISTA INVERTIDA*/
  83. ListaInvertida* CriaInvertida();
  84. ListaInvertida* InicializaInvertida(int id);
  85. void InsereInvertida(ListaInvertida* pai, char *curso , char *chave_primaria);
  86. int VerificaCurso(char *curso);
  87. void MostraListaInvertida(Aponta *Lista, ListaInvertida **ListaInvertida,int arquivo);
  88. void BuscaCurso(Aponta *lista, ListaInvertida** pai, int arquivo);
  89. /******************************************************************/
  90. /**********************************************************************************/
  91.  
  92. /******************************IMPLEMENTACAO DAS FUNCOES******************************/
  93. /* Funcao para criar a PED */
  94. Pilha * CriaPilha()
  95. {
  96.     Pilha *pi;
  97.     pi = (Pilha*) malloc(sizeof(Pilha));
  98.     pi->qtd = 0;
  99.     return pi;
  100. }
  101. /* Funcao para inserir elemento na PED */
  102. void InserePilha(Pilha *pi, int p, int arq)
  103. {
  104.     /*  Pode estar cheia ou pi == null */
  105.     pi->nrr[pi->qtd] = p;
  106.   pi->arq = arq;
  107.     pi->qtd++;
  108. }
  109. /* Funcao para remover elemento da PED */
  110. int RemovePilha(Pilha *pi)
  111. {
  112.     int topo = pi->nrr[pi->qtd-1];
  113.  
  114.     pi->qtd--;
  115.  
  116.     return topo;
  117. }
  118. /* Funcao para mostrar o menu ao usuario */
  119. int menu()
  120. {
  121.   int opcao;
  122.   printf("\n*************************************************\n");
  123.   printf("Incluir Registro                              (1)\n");
  124.   printf("Excluir Registro                              (2)\n");
  125.   printf("Atualizar Registro                            (3)\n");
  126.   printf("Mostrar Todos os Registros                    (4)\n");
  127.   printf("Mostrar Indices Primarios                     (5)\n");
  128.   printf("Mostrar Indices Secundarios                   (6)\n");
  129.   printf("Mostrar Lista Invertida                       (7)\n");
  130.   printf("Encerrar programa e Gerar Merging das Listas  (0)\n");
  131.   printf("*************************************************\n");
  132.   printf("Escolha a operacao desejada:\n");
  133.   scanf("%d",&opcao);
  134.   printf("\n");
  135.   return opcao;
  136. }
  137. /* Funcao que recebe a opcao escolhida pelo usuario no menu e realiza as operacoes necessarias */
  138. void escolha( int opcao, Aponta *lista1, Aponta *lista2, Aponta *lista3, ListaInvertida **listainvertida1, ListaInvertida **listainvertida2, Pilha *PED)
  139. {
  140.   int num_arq;
  141.  
  142.   switch(opcao)
  143.   {
  144.     case 1:
  145.       printf("Escolha o arquivo:\n");
  146.       printf("Lista1 (1)\n");
  147.       printf("Lista2 (2)\n");
  148.       scanf("%d",&num_arq);
  149.       getchar();
  150.       if (num_arq == 1)
  151.       {
  152.         IncluiRegistroLista(lista1,1,PED);
  153.       }
  154.       else
  155.       {
  156.         IncluiRegistroLista(lista2,2,PED);
  157.       }
  158.       break;
  159.     case 2:
  160.       printf("Escolha o arquivo:\n");
  161.       printf("Lista1 (1)\n");
  162.       printf("Lista2 (2)\n");
  163.       scanf("%d",&num_arq);
  164.       if (num_arq == 1)
  165.       {
  166.             MostraLista(lista1,1);
  167.           printf("\nEscolha o ID do registro a ser removido:\n");
  168.           int num;
  169.           scanf("%d", &num);
  170.           Exclusao(lista1, 1, num, PED);
  171.       }
  172.       else
  173.       {
  174.           MostraLista(lista2,2);
  175.           printf("\nEscolha o ID do registro a ser removido:\n");
  176.           int num;
  177.           scanf("%d", &num);
  178.           Exclusao(lista2, 2, num, PED);
  179.       }
  180.       break;
  181.     case 3:
  182.       printf("Escolha o arquivo:\n");
  183.       printf("Lista1 (1)\n");
  184.       printf("Lista2 (2)\n");
  185.       scanf("%d",&num_arq);
  186.       if (num_arq == 1)
  187.       {
  188.             MostraLista(lista1,1);
  189.           printf("\nEscolha o ID do registro a ser atualizado:\n");
  190.           int num;
  191.           scanf("%d", &num);
  192.           Atualizacao(lista1, num, 1);
  193.       }
  194.       else
  195.       {
  196.           MostraLista(lista2,2);
  197.           printf("\nEscolha o ID do registro a ser atualizado:\n");
  198.           int num;
  199.           scanf("%d", &num);
  200.  
  201.           Atualizacao(lista2, num, 2);
  202.       }
  203.       break;
  204.     case 4:
  205.       MostraLista(lista1,1);
  206.       MostraLista(lista2,2);
  207.       break;
  208.     case 5:
  209.       printf("Escolha o arquivo:\n");
  210.       printf("Lista1 (1)\n");
  211.       printf("Lista2 (2)\n");
  212.       scanf("%d",&num_arq);
  213.       if (num_arq == 1)
  214.         MostrarChavesPrimarias(lista1,1);
  215.       else
  216.         MostrarChavesPrimarias(lista2,2);
  217.       break;
  218.     case 6:
  219.       printf("Escolha o arquivo:\n");
  220.       printf("Lista1 (1)\n");
  221.       printf("Lista2 (2)\n");
  222.       scanf("%d",&num_arq);
  223.       if (num_arq == 1)
  224.         MostrarChavesSecundarias(lista1,1);
  225.       else
  226.         MostrarChavesSecundarias(lista2,2);
  227.       break;
  228.     case 7:
  229.       printf("Escolha o arquivo:\n");
  230.       printf("Lista1 (1)\n");
  231.       printf("Lista2 (2)\n");
  232.       scanf("%d",&num_arq);
  233.       if (num_arq == 1)
  234.         MostraListaInvertida(lista1,listainvertida1,1);
  235.       else
  236.         MostraListaInvertida(lista2,listainvertida2,2);
  237.       break;
  238.     case 0:
  239.       lista3->inicio = CombinaListas(lista1->inicio,lista2->inicio);
  240.       RemoveIguais(lista3);
  241.       CriaArquivoMerge(lista3);
  242.       break;
  243.     default:
  244.       printf("Opcao Invalida!!\n");
  245.   }
  246. }
  247. /* Funcao para criar uma lista */
  248. Aponta *CriaLista()
  249. {
  250.     Aponta* ptr = (Aponta*)malloc(sizeof(Aponta));
  251.     ptr->inicio = NULL;
  252.     ptr->fim = NULL;
  253.   ptr->tamanho = 0;
  254.     return ptr;
  255. }
  256. /* Funcao para alocar os elementos da lista */
  257. Lista *AlocaLista(int matricula, char *nome, char* curso, char turma, int op, int num_arq, int posicao, char *chave_primaria)
  258. {
  259.   Lista* novo = (Lista*)malloc(sizeof(Lista));
  260.   novo->matric = matricula;
  261.   strcpy(novo->nome, nome);
  262.   strcpy(novo->curso,curso);
  263.   novo->turma=turma;
  264.   strcpy(novo->chave_primaria, chave_primaria);
  265.   novo->op = op;
  266.   novo->posicao = posicao;
  267.   novo->num_arq = num_arq;
  268.   novo->ant = NULL;
  269.     novo->prox = NULL;
  270.     return novo;
  271. }
  272. /* Funcao para inserir ordenadamente na lista */
  273. void InsereOrdenado(Aponta *lista, int matricula, char *nome, char *curso, char turma, int op, int num_arq, int posicao, char *chave_primaria)
  274. {
  275.   Lista *atual = lista->inicio;
  276.   Lista *novo = AlocaLista(matricula, nome, curso, turma, op, num_arq, posicao, chave_primaria);
  277.  
  278.   /*
  279.   * loop para descobrir o maior elemento
  280.   */
  281.   while(atual != NULL && (strcmp(atual->chave_primaria, chave_primaria) < 0))
  282.   {
  283.     atual = atual->prox;
  284.   }
  285.  
  286.     /*
  287.      * parou o loop, entao a chave encontrada precisa ser armazenada antes do node atual
  288.      */
  289.   if(lista->inicio == NULL && lista->fim == NULL)
  290.   {
  291.     lista->inicio = lista->fim = novo;
  292.   }
  293.     else if(atual == NULL)
  294.   {
  295.         // significa que deve ser adicionada ao fim da lista
  296.         novo->ant = lista->fim;
  297.         novo->prox = NULL;
  298.         lista->fim->prox = novo;
  299.         lista->fim = novo;
  300.     }
  301.   else if(atual->ant == NULL)
  302.   {
  303.         // inserir no comeco da lista
  304.         novo->ant = NULL;
  305.         novo->prox = atual;
  306.         lista->inicio->ant = novo;
  307.         lista->inicio = novo;
  308.     }
  309.   else
  310.   {
  311.         // inserir em algum lugar no meio da lista
  312.         novo->ant = atual->ant;
  313.         novo->prox = atual;
  314.         novo->ant->prox = novo->prox->ant = novo;
  315.     }
  316.     lista->tamanho++;
  317. }
  318.  
  319. /* FUNCAO QUE RETORNO O NO DA LISTA A PARTIR DO INDICE */
  320. Lista *RetornaNo(Aponta *lista,int indice)
  321. {
  322.   if(indice >= 0 && indice < lista->tamanho)
  323.   {
  324.     Lista *aux = lista->inicio;
  325.     int i;
  326.     for(i=0;i< indice; i++)
  327.     {
  328.       aux = aux->prox;
  329.     }
  330.  
  331.     return aux;
  332.   }
  333.   else
  334.   {
  335.     printf("Indice invalido!\n");
  336.     return NULL;
  337.   }
  338. }
  339. /* Funcao que exibe na tela todos os elementos da Lista */
  340. void MostraLista(Aponta *lista,int arquivo)
  341. {
  342.   Lista *aux = lista->inicio;
  343.   int i=0;
  344.   if (arquivo == 1)
  345.     printf("\t\t\t REGISTROS ARQUIVO LISTA 1\n");
  346.   else
  347.     printf("\t\t\t REGISTROS ARQUIVO LISTA 2\n");
  348.   printf("MATRIC NOME                                             OP CURSO    TURMA|ID\n");
  349.   for(;aux!=NULL;aux=aux->prox)
  350.   {
  351.     ++i;
  352.     printf("0%d %s\t%d  %s\t\t%c|%d\n",aux->matric, aux->nome, aux->op, aux->curso, aux->turma, i);
  353.   }
  354. }
  355.  
  356. /* Funcao para liberar a memoria alocada por um no da lista */
  357. void free_node(Lista **n)
  358. {
  359.   if (n != NULL && *n != NULL)
  360.   {
  361.     free(*n);
  362.     *n = NULL;
  363.   }
  364. }
  365. /* Funcao para liberar a memoria alocada por um no da lista */
  366. void RemoveIguais(Aponta *lista)
  367. {
  368.   Lista *atual = lista->inicio;
  369.   Lista *subsequente = lista->inicio->prox;
  370.  
  371.   if (atual != NULL) {
  372.       while (atual->prox != NULL) {
  373.           if (strcmp(atual->chave_primaria, atual->prox->chave_primaria) == 0) {
  374.               subsequente = atual->prox->prox;
  375.               Lista *remove_node = atual->prox;
  376.               atual->prox = subsequente;
  377.               free_node(&remove_node);
  378.           } else {
  379.               atual = atual->prox;
  380.           }
  381.       }
  382.   }
  383. }
  384.  
  385. /* Função que verifica se a Lista esta vazia */
  386. int vazia (Aponta *lista)
  387. {
  388.   if(lista == NULL)
  389.   {/*Lista eh valida? */
  390.     return 0;
  391.   }
  392.   else
  393.   {
  394.     return 1; /*Lista nao esta vazia */
  395.   }
  396. }
  397.  
  398. void Atualizacao(Aponta *lista, int indice, int num_arq)
  399. {
  400.   int opcao,posicao,n,vezes;
  401.   char dado[50], nova_chave_primaria[31],string[100], nome[43], turma[3], matricula[7], curso[2], op[6];
  402.   Lista* aux = RetornaNo(lista,indice-1);
  403.   FILE *fp;
  404.   sprintf(matricula, "%06d", aux->matric);
  405.   sprintf(matricula, "%s", matricula);
  406.   sprintf(nova_chave_primaria, "%s", matricula);
  407. /*  Menu escolha do campo */
  408.   printf("\nO que deseja alterar?\n1 - MATRICULA\n2 - NOME\n3 - OP\n4 - CURSO\n5 - TURMA\n");
  409.   printf("\nQual o campo sera alterado? Escolha o campo de acordo com seu numero correspondente:\n");
  410.   scanf("%d", &opcao);
  411.   getchar();
  412.   printf("\nEscreva o valor do novo dado:\n");
  413.   scanf("%[^\n]%*c", dado);
  414.  
  415.   sprintf(op, "%d", aux->op);
  416.   sprintf(turma, "%c", aux->turma);
  417.   strcpy(nome,aux->nome);
  418.   strcpy(curso,aux->curso);
  419.   posicao = aux->posicao;
  420.   switch(opcao)
  421.   {
  422.             case 1:
  423.             /*  Mudar o valor do registro na lista */
  424.                 aux->matric = atoi(dado);
  425.         strcpy(nova_chave_primaria, dado);
  426.             /*  Mudando indices primarios e secundarios --> geracao de nova chave primaria*/
  427.         strncat(nova_chave_primaria, aux->nome, 24);
  428.         RemoveIndice(lista, indice-1);
  429.         InsereOrdenado(lista, atoi(dado), nome, curso, turma[0], atoi(op), num_arq, posicao, nova_chave_primaria);
  430.         strcpy(string,dado);
  431.         strcat(string, " ");
  432.         strcat(string, nome);
  433.         n = strlen(string);
  434.         vezes = 48 - n;
  435.         for(int i = 0; i < vezes; i++)
  436.             strcat(string, " ");
  437.         strcat(string, op);
  438.         strcat(string, "  ");
  439.         strcat(string, curso);
  440.         strcat(string,"       ");
  441.         strcat(string, turma);
  442.         AtualizaIndices(lista,num_arq);
  443.             /*  Mudanca no arquivo de registros*/
  444.         if(num_arq == 1)
  445.         {
  446.           fp = fopen("lista1.txt", "r+");
  447.           fseek(fp, aux->posicao, SEEK_SET); /*A partir do começo, 1 registro possui 64 bytes*/
  448.           fprintf(fp,"%s",string);
  449.           fclose(fp);
  450.         }
  451.         else
  452.         {
  453.           fp = fopen("lista2.txt", "r+");
  454.           fseek(fp, aux->posicao, SEEK_SET); /*A partir do começo, 1 registro possui 64 bytes*/
  455.           fprintf(fp,"%s",string);
  456.           fclose(fp);
  457.         }
  458.                 break;
  459.             case 2:
  460.             /*  Mudar o valor do registro na lista */
  461.                 strcpy(aux->nome, dado);
  462.         sprintf(matricula, "%s", nova_chave_primaria);
  463.             /*  Mudando indices primarios e secundarios --> geracao de nova chave primaria */
  464.         strncat(nova_chave_primaria, aux->nome, 24);
  465.         InsereOrdenado(lista, aux->matric, aux->nome, aux->curso, aux->turma, aux->op, aux->num_arq, aux->posicao, nova_chave_primaria);
  466.         RemoveIndice(lista, indice-1);
  467.         AtualizaIndices(lista,num_arq);
  468.             /*  Mudanca no arquivo de registros*/
  469.         if(num_arq == 1)
  470.         {
  471.           fp = fopen("lista1.txt", "r+");
  472.           fseek(fp, aux->posicao+7, SEEK_SET); /*A partir do começo, 1 registro possui 64 bytes*/
  473.           fprintf(fp, "%-40.40s", dado);
  474.           fclose(fp);
  475.         }
  476.         else
  477.         {
  478.           fp = fopen("lista2.txt", "r+");
  479.           fseek(fp, aux->posicao+7, SEEK_SET); /*A partir do começo, 1 registro possui 64 bytes*/
  480.           fprintf(fp, "%-40.40s", dado);
  481.           fclose(fp);
  482.         }
  483.                 break;
  484.             case 3:
  485.       /*    Mudar o valor do registro na lista */
  486.                 aux->op = atoi(dado);
  487.         strcpy(string,nova_chave_primaria);
  488.         strcat(string, " ");
  489.         strcat(string, nome);
  490.         n = strlen(string);
  491.         vezes = 48 - n;
  492.         for(int i = 0; i < vezes; i++)
  493.             strcat(string, " ");
  494.         strcat(string, dado);
  495.         strcat(string, "  ");
  496.         strcat(string, curso);
  497.         strcat(string,"       ");
  498.         strcat(string, turma);
  499.             /*  Mudanca no arquivo de registros*/
  500.         if(num_arq == 1)
  501.         {
  502.           fp = fopen("lista1.txt", "r+");
  503.           fseek(fp, aux->posicao, SEEK_SET); /*A partir do começo, 1 registro possui 64 bytes*/
  504.           fprintf(fp,"%s",string);
  505.           fclose(fp);
  506.         }
  507.         else
  508.         {
  509.           fp = fopen("lista2.txt", "r+");
  510.           fseek(fp, aux->posicao, SEEK_SET); /*A partir do começo, 1 registro possui 64 bytes*/
  511.           fprintf(fp,"%s",string);
  512.           fclose(fp);
  513.         }
  514.                 break;
  515.             case 4:
  516.             /*  Mudar o valor do registro na lista */
  517.                 strcpy(aux->curso, dado);
  518.         strcpy(string,nova_chave_primaria);
  519.         strcat(string, " ");
  520.         strcat(string, nome);
  521.         n = strlen(string);
  522.         vezes = 48 - n;
  523.         for(int i = 0; i < vezes; i++)
  524.             strcat(string, " ");
  525.         strcat(string, op);
  526.         strcat(string, "  ");
  527.         strcat(string, dado);
  528.         strcat(string,"       ");
  529.         strcat(string, turma);
  530.             /*  Mudanca no arquivo de registros*/
  531.         if(num_arq == 1)
  532.         {
  533.           fp = fopen("lista1.txt", "r+");
  534.           fseek(fp, aux->posicao, SEEK_SET); /*A partir do começo, 1 registro possui 64 bytes*/
  535.           fprintf(fp,"%s",string);
  536.           fclose(fp);
  537.         }
  538.         else
  539.         {
  540.           fp = fopen("lista2.txt", "r+");
  541.           fseek(fp, aux->posicao, SEEK_SET); /*A partir do começo, 1 registro possui 64 bytes*/
  542.           fprintf(fp,"%s",string);
  543.           fclose(fp);
  544.         }
  545.                 break;
  546.             case 5:
  547.             /*  Mudar o valor do registro na lista */
  548.                 aux->turma=dado[0];
  549.         strcpy(string,nova_chave_primaria);
  550.         strcat(string, " ");
  551.         strcat(string, nome);
  552.         n = strlen(string);
  553.         vezes = 48 - n;
  554.         for(int i = 0; i < vezes; i++)
  555.             strcat(string, " ");
  556.         strcat(string, op);
  557.         strcat(string, "  ");
  558.         strcat(string, curso);
  559.         strcat(string,"       ");
  560.         strcat(string, dado);
  561.                 /*  Mudanca no arquivo de registros*/
  562.         if(num_arq == 1)
  563.         {
  564.           fp = fopen("lista1.txt", "r+");
  565.           fseek(fp, aux->posicao, SEEK_SET); /*A partir do começo, 1 registro possui 64 bytes*/
  566.           fprintf(fp,"%s",string);
  567.           fclose(fp);
  568.         }
  569.         else
  570.         {
  571.           fp = fopen("lista2.txt", "r+");
  572.           fseek(fp, aux->posicao, SEEK_SET); /*A partir do começo, 1 registro possui 64 bytes*/
  573.           fprintf(fp,"%s",string);
  574.           fclose(fp);
  575.         }
  576.                 break;
  577.             default:
  578.                 printf("Nao existe esse campo!\n");
  579.                 break;
  580.         }
  581.     AtualizaIndices(lista,num_arq);
  582. }
  583. /* FUNCAO PARA EXCLUSAO DE UM REGISTRO FAZENDO O DEVIDO ARMAZENAMENTO NA PED PARA O REUSO DE ESPACOS */
  584. void Exclusao(Aponta* lista, int arquivo, int indice, Pilha *PED)
  585. {
  586.     Lista* aux = RetornaNo(lista,indice-1);
  587.  
  588.     int nrr = aux->posicao; /* Posicao relativa do resgistro. */
  589.  
  590.     RemoveIndice(lista, indice-1);
  591.  
  592.     FILE *fp;
  593.     if(arquivo == 1)
  594.         fp = fopen("lista1.txt", "r+");
  595.     else
  596.         fp = fopen("lista2.txt", "r+");
  597.     fseek(fp, nrr, SEEK_SET);  /*A partir do começo, 1 registro possui 64 bytes*/
  598.     fprintf(fp, "*"); /* Adicionando marcador ao 1 byte do registro para reuso */
  599.     fclose(fp);
  600.  
  601.     InserePilha(PED, nrr, arquivo); /* Inserindo espaco na PED */
  602.     AtualizaIndices(lista,arquivo); /* Atualizando indices */
  603. }
  604. /* Funcao para liberar todos elementos da lista */
  605. void libera(Aponta* lista)
  606. {
  607.   Lista* q = lista->inicio;
  608.   while (q!=NULL)
  609.   {
  610.       Lista* t = q->prox;
  611.       free(q);
  612.       q = t;
  613.   }
  614.   free(lista);
  615. }
  616. /* Funcao para remover um elemento da lista dado seu devido indice */
  617. void RemoveIndice(Aponta *lista, int indice)
  618. {
  619.   indice++;
  620.   if(indice == 1)
  621.   {
  622.     RetiraInicio(lista);
  623.     return;
  624.   }
  625.  
  626.   if(indice == lista->tamanho)
  627.   {
  628.     RetiraFim(lista);
  629.     return;
  630.   }
  631.   indice--;
  632.   Lista *atual = RetornaNo(lista,indice);
  633.   Lista * seguinte = RetornaNo(lista,indice+1);
  634.  
  635.   if(atual != NULL)
  636.   {
  637.     Lista  *anterior = RetornaNo(lista,indice-1);
  638.     if(anterior == NULL)
  639.     {
  640.       seguinte->ant = NULL;
  641.       return;
  642.     }
  643.     anterior->prox = seguinte;
  644.     seguinte->ant = anterior;
  645.     lista->tamanho--;
  646.     free(atual);
  647.   }
  648. }
  649. /* Funcao para remover um elemento do fim da lista */
  650. void RetiraFim(Aponta *lista)
  651. {
  652.   if (vazia(lista) == 1)
  653.   {
  654.     Lista *aux = lista->fim;
  655.     lista->fim = lista->fim->ant;
  656.     lista->fim->prox = NULL;
  657.     free(aux);
  658.     lista->tamanho--;  
  659.   }
  660.   else
  661.   {
  662.     printf("Lista esta vazia!\n");
  663.     return ;
  664.   }
  665. }
  666. /* Funcao para remover um elemento do inicio da lista */
  667. void RetiraInicio(Aponta *lista)
  668. {
  669.   if( (vazia(lista) == 1))
  670.   {
  671.     Lista * aux = lista->inicio->prox;
  672.     aux->ant = NULL;  
  673.     free(lista->inicio);
  674.     lista->inicio = aux;
  675.     lista->tamanho--;
  676.   }
  677.   else
  678.   {
  679.     printf("Lista esta vazia!\n");
  680.     return ;
  681.   }
  682. }
  683. /* Funcao para criar o arquivo com os indices ordenados da lista 1 e 2 */
  684. void CriaArquivoMerge(Aponta *lista)
  685. {
  686.   FILE *arquivo;
  687.   Lista *aux = lista->inicio;
  688.  
  689.   arquivo = fopen("MergeListas.ind", "w");
  690.   fprintf(arquivo, "CHAVE-PRIMARIA\t\t\t\t\tCURSO\n");
  691.  
  692.   if(arquivo == NULL)
  693.     {
  694.     printf("Erro ao tentar abrir o arquivo MergeListas.ind!");
  695.     exit(1);
  696.   }
  697.   for(;aux!=NULL;aux=aux->prox)
  698.   {
  699.     fprintf(arquivo, "%s\t", aux->chave_primaria);
  700.     fprintf(arquivo, " %s\n", aux->curso);
  701.   }
  702.  
  703.   fclose(arquivo);
  704. }
  705. /* Funcao para manipulacao de strings das listas separando cada campo */
  706. void ManipulaString(char *linha, int desloca, int opcao, Aponta *lista)
  707. {
  708.   int i, k=0, eh_op=0, eh_nome=0, eh_curso=0, eh_matricula=0,eh_turma=0, tamanho = strlen(linha);
  709.   char aux[5], chave_primaria[31], MATRIC[7], nome[43], OP[3], Curso[3], Turma;
  710.  
  711.   for(i=0;i<tamanho;i++)
  712.   {
  713.     if(eh_matricula == 0) /* Verifica se eh numero e armazena matric como string */
  714.     {
  715.       while(linha[i] != ' ' && eh_matricula == 0)
  716.       {
  717.         MATRIC[i] = linha[i];
  718.         i++;
  719.       }
  720.       MATRIC[i] = '\0';
  721.       eh_matricula = 1;
  722.     }
  723.  
  724.     if( linha[i] == ' '  && eh_nome ==0) /* Armazena Nome */
  725.     {
  726.       i++;
  727.       while(atoi(aux) == 0 )
  728.       {
  729.         nome[k] = linha[i];
  730.  
  731.         k++;
  732.         i++;
  733.         aux[0] = linha[i]; /* Para no ultimo caracter, antes de um numero */
  734.       }
  735.       nome[k] = '\0';
  736.       k=0;
  737.       eh_nome = 1;
  738.     }
  739.  
  740.     if(atoi(aux) != 0 && eh_op==0 && eh_nome==1) /* Armazena OP como string */
  741.     {
  742.       aux[0] = linha[i];
  743.  
  744.       while(atoi(aux) != 0 )
  745.       {
  746.         OP[k] = linha[i];
  747.         k++; i++;
  748.         aux[0] = linha[i];
  749.       }
  750.       OP[k] = '\0';
  751.       eh_op =1;
  752.       i++;
  753.       k=0;
  754.     }
  755.     aux[0] = linha[i];
  756.     if( linha[i] != ' ' && eh_curso == 0 && eh_op == 1)  /* Sigla do Curso */
  757.     {
  758.       Curso[0] = linha[i];
  759.       Curso[1] = linha[++i];
  760.       Curso[2] = '\0';
  761.       eh_curso = 1;
  762.       i++;
  763.     }
  764.  
  765.     if( linha[i] != ' ' && eh_turma == 0 && eh_curso == 1) /* Letra da Turma */
  766.     {
  767.       Turma=linha[i];
  768.       eh_turma = 1;
  769.     }
  770.   }
  771.   strcpy(chave_primaria,MATRIC);
  772.   strncat(chave_primaria ,nome ,24); /* Cria a chave primaria a partir da concatenacao da matricula com nome */
  773.   InsereOrdenado(lista, atoi(MATRIC), nome, Curso, Turma, atoi(OP), opcao, desloca, chave_primaria);
  774. }
  775. /* Funcao para criacao dos indices primarios e secundarios */
  776. void CriaIndices(Aponta* lista,int opcao)
  777. {
  778.     FILE *arquivo;
  779.         int byteoff = 0; /* Variavel que vai ser usada para controlar o byte de cada linha */
  780.         int fim_arquivo = 0;
  781.     char linha[100];
  782.    
  783.         if(opcao == 1)
  784.         {
  785.         arquivo = fopen("lista1.txt","rb");
  786.     }
  787.     else if(opcao == 2)
  788.         {
  789.         arquivo = fopen("lista2.txt","rb");
  790.     }
  791.  
  792.     /* Descobrindo o tamanho do arquivo */
  793.     fseek(arquivo, 0L, SEEK_END); /* Aponto para o fim do arquivo */
  794.     fim_arquivo = ftell(arquivo); /* Retorna o valor do fim do arquivo */
  795.     fseek(arquivo, 0, SEEK_SET); /* Aponta de volta para o inicio do arquivo para fazer a leitura */
  796.     /* -------------------------------- */
  797.     printf("\nTamanho do Arquivo Lista%d.txt: %d\n", opcao, fim_arquivo);
  798.     if(arquivo == NULL) /* Verifica se abriu o arquivo corretamente */
  799.     {
  800.       printf("\nFalha ao tentar abrir o arquivo lista%d.txt\n",opcao);
  801.     }
  802.     else
  803.     {
  804.       while(!feof(arquivo)) /* Enquanto nao encontrar o fim do arquivo */
  805.       {
  806.         fgets(linha, sizeof(linha), arquivo);
  807.         if (byteoff >= fim_arquivo)
  808.           break;    
  809.         ManipulaString(linha, byteoff, opcao, lista); /* Separa os campos da linha em strings */
  810.         byteoff += 64; /* Cada registro possui 64 bytes */
  811.       }
  812.       EscreveIndicesPrimarios(lista, opcao);  /* Escreve as informaçoes necessarias no indice primario */
  813.             EscreveIndicesSecundarios(lista, opcao);  /* Escreve as informaçoes necessarias no indice secundario */
  814.     }
  815.     fclose(arquivo);
  816. }
  817. /* Função que escreve as informações no indiceprimario1.ind ou no indiceprimario2.ind */
  818. void EscreveIndicesPrimarios(Aponta *lista, int num_arq)
  819. {
  820.   FILE *arquivo;
  821.   Lista *aux = lista->inicio;
  822.  
  823.   if(num_arq == 1)
  824.     {
  825.     arquivo = fopen("indiceprimario1.ind", "w");
  826.     fprintf(arquivo, "CHAVE-PRIMARIA\t\t\tBYTE-OFFSET\n");
  827.   }
  828.     else
  829.     {
  830.     arquivo = fopen("indiceprimario2.ind", "w");
  831.     fprintf(arquivo, "CHAVE-PRIMARIA\t\t\tBYTE-OFFSET\n");
  832.   }
  833.  
  834.   if(arquivo == NULL)
  835.     {
  836.     printf("Erro ao tentar abrir o arquivo indicelista%d.ind!", num_arq);
  837.     exit(2);
  838.   }
  839.   for(;aux!=NULL;aux=aux->prox)
  840.   {
  841.     fprintf(arquivo, "%s\t", aux->chave_primaria);
  842.     fprintf(arquivo, "%d\n", aux->posicao);
  843.   }
  844.  
  845.   fclose(arquivo);
  846. }
  847. /* Funcao que inclui as informacoes de um novo registro na Lista */
  848. void IncluiRegistroLista(Aponta *lista, int arquivo, Pilha *PED)
  849. {
  850.   FILE *fp;
  851.   int  num_arq, posicao=0,n,vezes,mat;
  852.   char string[100],nome[43], turma[3], matricula[7], curso[2], op[6], chave_primaria[31], turmac;
  853.  
  854.   printf("Qual é a matrícula do novo aluno?\n");
  855.   scanf("%[^\n]%*c", matricula);
  856.   strcpy(string, matricula);
  857.   mat = atoi(string);
  858.   sprintf(chave_primaria, "%s", string);
  859.  
  860.   printf("Qual é o nome do novo aluno?\n");
  861.   scanf("%[^\n]%*c", nome);
  862.   strncat(chave_primaria, nome, 24);
  863.  
  864.   printf("Qual é o OP do novo aluno?\n");
  865.   scanf("%[^\n]%*c", op);
  866.  
  867.   printf("Qual é o curso do novo aluno?\n");
  868.   scanf("%[^\n]%*c", curso);
  869.  
  870.   printf("Qual é a turma do novo aluno?\n");
  871.   scanf("%[^\n]%*c", turma);
  872.  
  873.   strcat(string, " ");
  874.   strcat(string, nome);
  875.   n = strlen(string);
  876.   vezes = 48 - n;
  877.   for(int i = 0; i < vezes; i++)
  878.       strcat(string, " ");
  879.   strcat(string, op);
  880.   strcat(string, "  ");
  881.   strcat(string, curso);
  882.   strcat(string,"       ");
  883.   strcat(string, turma);
  884.  
  885.   if ( PED->qtd != 0 && PED->arq == arquivo)
  886.     {
  887.         /*Caso tenha ocorrido remocoes
  888.         *   Adiciona no lugar onde tem espaço? -> PED */
  889.         int nrr = RemovePilha(PED);
  890.     posicao = nrr;
  891.     if (arquivo == 1)
  892.       fp = fopen("lista1.txt", "r+");
  893.     else
  894.           fp = fopen("lista2.txt", "r+");
  895.         fseek(fp, nrr, SEEK_SET);
  896.     fprintf(fp,"%s",string);
  897.     fclose(fp);
  898.     }
  899.   else
  900.   {
  901.     if(arquivo == 1)
  902.     {
  903.       fp = fopen("lista1.txt","a");
  904.       fprintf(fp,"%s\n",string);
  905.       fclose(fp);
  906.       posicao = lista->fim->posicao + 64;
  907.     }
  908.     else
  909.     {
  910.       fp = fopen("lista2.txt","a");
  911.       fprintf(fp,"%s\n",string);
  912.       fclose(fp);
  913.       posicao = lista->fim->posicao + 64;
  914.     }
  915.   }
  916.   turmac=turma[0];
  917.   InsereOrdenado(lista, mat, nome, curso, turmac, atoi(op), arquivo, posicao, chave_primaria);
  918.   AtualizaIndices(lista,arquivo);
  919. }
  920. /*Funcao para fazer o merging das duas listas */
  921. Lista *CombinaListas(Lista *esquerda, Lista *direita)
  922. {
  923.     if (esquerda==NULL)
  924.   {
  925.     return direita;
  926.     }
  927.   else if (direita==NULL)
  928.   {
  929.         return esquerda;
  930.     }
  931.   else if (strcmp(esquerda->chave_primaria, direita->chave_primaria) < 0)
  932.   {
  933.         esquerda->prox = CombinaListas(esquerda->prox,direita);
  934.         (esquerda->prox)->ant = esquerda;
  935.         esquerda->ant = NULL;
  936.         return esquerda;
  937.     }
  938.   else
  939.   {
  940.         direita->prox = CombinaListas(esquerda,direita->prox);
  941.         (direita->prox)->ant = direita;
  942.         direita->ant = NULL;
  943.         return direita;
  944.     }
  945. }
  946. /* Função que escreve as informações no indicesecundario1.txt ou no indicesecundario2.txt */
  947. void EscreveIndicesSecundarios(Aponta *lista, int num_arq)
  948. {
  949.   FILE *arquivo;
  950.   Lista *aux = lista->inicio;
  951.  
  952.   if(num_arq == 1)
  953.   {
  954.     arquivo = fopen("indicesecundario1.ind", "w");
  955.     fprintf(arquivo, "CURSO\t\tCHAVE PRIMARIA\n");
  956.   }
  957.   else
  958.   {
  959.     arquivo = fopen("indicesecundario2.ind", "w");
  960.     fprintf(arquivo, "CURSO\t\tCHAVE PRIMARIA\n");
  961.   }
  962.  
  963.   if(arquivo == NULL)
  964.   {
  965.     printf("Erro ao tentar abrir o arquivo indicesecundario%d.ind!", num_arq);
  966.     exit(2);
  967.   }
  968.     for(;aux!=NULL;aux=aux->prox)
  969.   {
  970.     fprintf(arquivo, "%s\t", aux->curso);
  971.     fprintf(arquivo, "%s\n", aux->chave_primaria);
  972.   }
  973.  
  974.   fclose(arquivo);
  975. }
  976. /* Função que regrava os arquivos indices caso haja mudanças */
  977. void AtualizaIndices(Aponta *lista, int num_arq)
  978. {
  979.   EscreveIndicesPrimarios(lista, num_arq);
  980.   EscreveIndicesSecundarios(lista, num_arq);
  981. }
  982. /* Mostra indices primarios com seus respectivos PRRs */
  983. void MostrarChavesPrimarias(Aponta *lista,int arquivo)
  984. {
  985.   int i=0;
  986.   Lista *aux = lista->inicio;
  987.   printf("Indice primario do arquivo %d:\n\n",arquivo);
  988.   printf("Chave Primaria                |PRR|ID\n");
  989.   for(;aux!=NULL;aux=aux->prox)
  990.   {
  991.     ++i;
  992.     printf("%s|%d|%d\n", aux->chave_primaria, aux->posicao, i);
  993.   }
  994. }
  995. /* Mostra indice secundarios com seus respectivos ID */
  996. void MostrarChavesSecundarias(Aponta *lista,int arquivo)
  997. {
  998.   int i=0;
  999.   Lista *aux = lista->inicio;
  1000.   printf("Indice secundario do arquivo %d:\n\n",arquivo);
  1001.   printf("Curso | Chave Primaria           |ID\n");
  1002.   for(;aux!=NULL;aux=aux->prox)
  1003.   {
  1004.     ++i;
  1005.     printf("%s|%s|%d\n", aux->curso, aux->chave_primaria, i);
  1006.   }
  1007. }
  1008. /* Função que verifica o registro a partir do curso */
  1009. int verifica_curso(char *curso)
  1010. {
  1011.   if(strcmp(curso , "CC") == 0)
  1012.     return 1;
  1013.   else if(strcmp(curso , "EC") == 0)
  1014.     return 2;
  1015.   else if (strcmp(curso , "EM") == 0)
  1016.     return 3;
  1017. return 0;
  1018. }
  1019. /*Funcao que cria a lista invertida*/
  1020. ListaInvertida* CriaInvertida()
  1021. {
  1022.   return NULL;
  1023. }
  1024. /*Funcao que inicializa a lista invertida*/
  1025. ListaInvertida* InicializaInvertida(int id)
  1026.  {
  1027.   ListaInvertida* novo = (ListaInvertida*) malloc(sizeof(ListaInvertida));
  1028.   novo->id = id;
  1029.   novo->prox = NULL;
  1030.   return novo;
  1031. }
  1032. /*Funcao que insere elementos na lista invertida*/
  1033. void InsereInvertida(ListaInvertida* pai, char *curso , char *chave_primaria)
  1034. {
  1035.   ListaInvertida* filho = (ListaInvertida*) malloc(sizeof(ListaInvertida));
  1036.   strcpy(filho->chave_primaria , chave_primaria);
  1037.   strcpy(filho->curso , curso);
  1038.   filho->prox = NULL;
  1039.   if(pai->prox == NULL)
  1040.     {
  1041.     pai->prox = filho;
  1042.   }
  1043.   else
  1044.   {
  1045.     ListaInvertida* vertice = pai;
  1046.     ListaInvertida* temp;
  1047.     while(vertice != NULL)
  1048.     {
  1049.       temp = vertice;
  1050.       vertice = vertice->prox;
  1051.     }
  1052.     temp->prox = filho;
  1053.   }
  1054. }
  1055. /* Funcao que mostra elementos filhos na lista invertida */
  1056. void printa_filho(ListaInvertida* n)
  1057. {
  1058.  
  1059.   if(n == NULL)
  1060.     return;
  1061.  
  1062.   printf("\n%s  %s", n->chave_primaria,n->curso);
  1063.   printa_filho(n->prox);
  1064. }
  1065. /* Funcao que mostra elementos pais na lista invertida */
  1066. void printa_pai(ListaInvertida* n)
  1067. {
  1068.   if(n == NULL)
  1069.     return;
  1070.  
  1071.   printf("Chave Primaria: \t\tCurso:\t");
  1072.   printa_filho(n->prox);
  1073.   printf("\n");
  1074. }
  1075. /* Funcao que mostra a lista invertida de determinado arquivo */
  1076. void MostraListaInvertida(Aponta *Lista, ListaInvertida **ListaInvertida,int arquivo)
  1077. {
  1078.   int i;
  1079.   BuscaCurso(Lista, ListaInvertida, arquivo);
  1080.   for (i = 0; i < 3; i++ )
  1081.     {
  1082.     printf("\n");
  1083.       printa_pai(ListaInvertida[i]);
  1084.     }
  1085.  
  1086. }
  1087. /* Funcao que pesquisa o curso a partir da lista invertida */
  1088. void BuscaCurso(Aponta *lista, ListaInvertida** pai, int arquivo)
  1089. {
  1090.   int recebe;
  1091.   Lista *aux = lista->inicio;
  1092.   for(; aux != NULL; aux = aux->prox ) /* Imprime todas as informações até chegar ao fim da Lista */
  1093.   {
  1094.     recebe = verifica_curso(aux->curso);
  1095.  
  1096.    if(recebe == 1 && aux->num_arq == arquivo) /* CC*/
  1097.       InsereInvertida(pai[0] , aux->curso , aux->chave_primaria);
  1098.     if(recebe == 2 && aux->num_arq == arquivo) /* EC*/
  1099.       InsereInvertida(pai[1] , aux->curso , aux->chave_primaria);
  1100.     if(recebe == 3 && aux->num_arq == arquivo) /* EM*/
  1101.       InsereInvertida(pai[2] , aux->curso , aux->chave_primaria);
  1102.   }
  1103. }
  1104. /* Main do programa */
  1105. int main()
  1106. {
  1107.   int i,opcao;
  1108.   Pilha *PED = CriaPilha();
  1109.     Aponta *Lista1 = CriaLista();
  1110.   Aponta *Lista2 = CriaLista();
  1111.   Aponta *Lista3 = CriaLista();
  1112.  
  1113.     ListaInvertida** ListaInvertida1 = (ListaInvertida**) malloc(sizeof(ListaInvertida*));
  1114.     ListaInvertida** ListaInvertida2 = (ListaInvertida**) malloc(sizeof(ListaInvertida*));
  1115.     /* For para alocar a lista invertida com respeito a adjacencia com os cursos */
  1116.     for(i=0 ; i < 9; i++)
  1117.     {
  1118.      ListaInvertida1[i] = InicializaInvertida(i+1);
  1119.      ListaInvertida2[i] = InicializaInvertida(i+1);
  1120.     }
  1121.  
  1122.   CriaIndices(Lista1,1);
  1123.   CriaIndices(Lista2,2);
  1124.  
  1125.   do
  1126.   {
  1127.     opcao = menu();
  1128.     escolha(opcao , Lista1, Lista2, Lista3, ListaInvertida1, ListaInvertida2, PED);
  1129.   }while( opcao != 0);
  1130.  
  1131.   libera(Lista1);
  1132.   libera(Lista2);
  1133.   Lista1 = NULL;
  1134.   Lista2 = NULL;
  1135.   return 0;
  1136. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement