aula 285

Como excluir contato da agenda de aniversário em arquivo texto?

Como excluir um contato da agenda de aniversário salva em arquivo texto? É esta dúvida que vamos resolver na aula de hoje sobre arquivo texto na Linguagem C.

Se você está acompanhando o Curso de Programação C desde o início, você deve se lembrar que lá na aula 215 nós iniciamos a criação de uma agenda de aniversários para praticar o uso de arquivos em C. Hoje vamos acrescentar uma função ao nosso código para realizar a exclusão de um contato da nossa agenda.

A exclusão ela não ocorre propriamente no arquivo, mas no vetor em memória. Assim, precisamos carregar todos os contatos salvos no arquivo para a memória. Feito isso, podemos agora fazer uma função que irá imprimir todos os contatos na tela e perguntar ao usuário qual contato ele deseja excluir.

Como o primeiro índice válido do vetor é o 0 e nosso procedimento imprimir inicia a partir do 1, precisamos subtrair 1 no valor que o usuário digitar e verificar se é um índice válido, ou seja, se está entre 0 e quant – 1, sendo quant a quantidade de contatos no vetor.

Se for um índice válido, liberamos a memória alocado para o contato daquela posição e, como é um vetor, não podemos deixar um “buraco” ou uma posição vazia no meio do vetor, então copiamos o último contato (que está na posição quant – 1) para a posição onde acabamos de remover o contato.

Esta lógica é implementada no trecho de código a seguir.

/*
      Procedimento para excluir um contato
*/
int excluir_contato(Contato **c, int quant){
    int id;

    imprimir(c, quant);

    printf("\n\tDigite o codigo do contato que deseja excluir: \n");
    scanf("%d", &id);
    getchar();
    id--;

    if(id >= 0 && id < quant){
        // apagar contato
        free(c[id]);
        if(id < quant - 1)
            c[id] = c[quant - 1];
        return -1; // excluído com sucesso
    }
    else{
        printf("\n\tCodigo invalido!\n");
        return 0; // nenhum contato excluído
    }
}

Observe que o contato foi excluído apenas do vetor de contatos em memória. Para que isso se reflita no arquivo texto é necessário escrever os contatos novamente no arquivo, salvando assim as alterações.

Código de exemplo completo em C para a Agenda de Aniversários

#include <stdio.h>
#include <stdlib.h>

/*
          AGENDA DE ANIVERSÁRIOS - Como excluir um contato

          Código escrito por Wagner Gaspar
          Outubro de 2021
*/

typedef struct{
    char nome[50];
    int dia, mes, ano;
}Contato;

void imprimir(Contato **c, int quant){
    int i;

    printf("\n\t\tLista de Contatos:\n");
    printf("\t--------------------------------\n");
    for(i = 0; i < quant; i++){
        printf("\t%d = %2d/%2d/%4d\t%s\n", i+1, c[i]->dia, c[i]->mes, c[i]->ano, c[i]->nome);
    }
    printf("\t--------------------------------\n");
}

int cadastrar_contato(Contato **c, int quant, int tam){

    if(quant < tam){
        Contato *novo = malloc(sizeof(Contato));

        printf("\nDigite o nome do contato: ");
        scanf("%50[^\n]", novo->nome);
        printf("\nDigite a data de aniversario dd mm aaaa: ");
        scanf("%d%d%d", &novo->dia, &novo->mes, &novo->ano);
        getchar();
        c[quant] = novo;
        return 1;
    }
    else{
        printf("\n\tImpossivel novo cadastro. Vetor cheio!\n");
        return 0;
    }
}

void alterar_contato(Contato **c, int quant){
    int id;

    imprimir(c, quant);

    printf("\n\tDigite o codigo do contato que deseja alterar: \n");
    scanf("%d", &id);
    getchar();
    id--;

    if(id >= 0 && id < quant){
        Contato *novo = malloc(sizeof(Contato));
        printf("\nDigite o nome do contato: ");
        scanf("%50[^\n]", novo->nome);
        printf("\nDigite a data de aniversario dd mm aaaa: ");
        scanf("%d%d%d", &novo->dia, &novo->mes, &novo->ano);
        getchar();
        c[id] = novo;
    }
    else
        printf("\n\tCodigo invalido!\n");
}

// -------- excluir contato ------------------------------
int excluir_contato(Contato **c, int quant){
    int id;

    imprimir(c, quant);

    printf("\n\tDigite o codigo do contato que deseja excluir: \n");
    scanf("%d", &id);
    getchar();
    id--;

    if(id >= 0 && id < quant){
        // apagar contato
        free(c[id]);
        if(id < quant - 1)
            c[id] = c[quant - 1];
        return -1; // excluido com sucesso
    }
    else{
        printf("\n\tCodigo invalido!\n");
        return 0; // nenhum contato excluido
    }
}

void salvar(Contato **c, int quant, char arq[]){
    FILE *file = fopen(arq, "w");
    int i;

    if(file){
        fprintf(file, "%d\n", quant);
        for(i = 0; i < quant; i++){
            fputs(c[i]->nome, file);
            fputc('\n', file);
            fprintf(file, "%d %d %d\n", c[i]->dia, c[i]->mes, c[i]->ano);
        }
        fclose(file);
    }
    else
        printf("\n\tNAO FOI POSSIVEL ABRIR/CRIAR O ARQUIVO!\n");
}

int ler_arquivo(Contato **c, char arq[]){
    FILE *file = fopen(arq, "r");
    int quant = 0, i;
    Contato *novo = malloc(sizeof(Contato));

    if(file){
        fscanf(file, "%d\n", &quant);
        for(i = 0; i < quant; i++){
            //fgets(novo->nome, 50, file);
            fscanf(file, "%50[^\n]", novo->nome);
            fscanf(file, "%d %d %d\n", &novo->dia, &novo->mes, &novo->ano);
            c[i] = novo;
            novo = malloc(sizeof(Contato));
        }
        fclose(file);
    }
    else
        printf("\n\tNAO FOI POSSIVEL ABRIR/CRIAR O ARQUIVO!\n");
    return quant;
}

int main(){

    Contato *agenda[50];
    char arquivo[] = {"agenda.txt"};
    int opcao, tam = 50, quant = 0;

    do{
        printf("\n\t0 - Sair\n\t1 - Cadastrar\n\t2 - Alterar\n\t3 - Imprimir\n\t4 - Salvar\n\t5 - Ler arquivo\n\t6 - Excluir Contato\n");
        scanf("%d", &opcao);
        getchar();

        switch(opcao){
        case 1:
            quant += cadastrar_contato(agenda, quant, tam);
            break;
        case 2:
            alterar_contato(agenda, quant);
            break;
        case 3:
            imprimir(agenda, quant);
            break;
        case 4:
            salvar(agenda, quant, arquivo);
            break;
        case 5:
            quant = ler_arquivo(agenda, arquivo);
            break;
        case 6:
            quant += excluir_contato(agenda, quant);
            break;
        default:
            if(opcao != 0)
                printf("\n\tOpcao invalida!!!\n");
        }
    }while(opcao != 0);

    return 0;
}

Deixe um comentário

4 + 17 =

Wagner Gaspar

Capixaba de São Gabriel da Palha, Espírito Santo. Bacharel em Ciência da Computação pela Universidade Federal do Amazonas e mestre em informática pela Universidade Federal do Espírito Santo.