From e453d4e8e718ad54b2abae74c93de4b49dea4a5f Mon Sep 17 00:00:00 2001 From: Ryu Date: Thu, 11 Jun 2026 19:04:32 -0300 Subject: [PATCH] FEAT: implementar busca, remocao e persistencia da primeira fase --- include/contact.h | 21 ++-- include/storage.h | 25 +---- src/contact.c | 147 +++++++++++++++++++++++--- src/main.c | 93 ++++++++-------- src/storage.c | 61 +++++------ tests/2026-06-11-add-search-remove.md | 16 +++ 6 files changed, 245 insertions(+), 118 deletions(-) create mode 100644 tests/2026-06-11-add-search-remove.md diff --git a/include/contact.h b/include/contact.h index 85b944f..24ea224 100644 --- a/include/contact.h +++ b/include/contact.h @@ -1,20 +1,19 @@ #ifndef CONTACT_H -#define CONTACT_H +#define CONTACT_H -#define MAX_NAME 100 -#define MAX_PHONE 20 +#define MAX_NAME 100 +#define MAX_PHONE 20 typedef struct { + int id; char name[MAX_NAME]; char phone[MAX_PHONE]; } Contact; -void addContact(Contact contacts[], int *count); // Prototipo de função para adicionar um contato. -void listContacts(Contact contacts[], int count); // Prototipo de função para listar os contatos. -void removeContact(Contact contacts[], int *count); // Prototipo de função para remover um contato. -int findContact(Contact contacts[], int id); // Prototipo de função para buscar um contato por ID. +void addContact(Contact contacts[], int *count); +void listContacts(Contact contacts[], int count); +void searchContacts(Contact contacts[], int count); +int findContact(Contact contacts[], int count, const char *query); +void removeContact(Contact contacts[], int *count); - -#endif -// Prototipo de função para buscar um contatos por nome. -// Podde ser melhorada para retornar um ponteiro para o contato encontrado ou NULL se não encontrado. \ No newline at end of file +#endif diff --git a/include/storage.h b/include/storage.h index 96b7126..c232a8f 100644 --- a/include/storage.h +++ b/include/storage.h @@ -1,24 +1,9 @@ -#ifndef STORAGE_H -#define STORAGE_H +#ifndef STORAGE_H +#define STORAGE_H #include "contact.h" -// Prototipo de função para salvar os contatos em um arquivo. -void saveContacts( - Contact contacts[], - int count -); +void saveContacts(Contact contacts[], int count); +void loadContacts(Contact contacts[], int *count); -// Prototipo de função para carregar os contatos do arquivo. -void loadContacts( - Contact contacts[], - int *count -); - -// Prototipo de função para remover um contato do arquivo. - -// Prototipo de função para buscar um contato por nome no arquivo. - -// As funções removeContact e findContact ainda precisam ser implementadas, mas os protótipos já estão definidos para futuras implementações. - -#endif \ No newline at end of file +#endif diff --git a/src/contact.c b/src/contact.c index fc701b3..7b102dd 100644 --- a/src/contact.c +++ b/src/contact.c @@ -1,31 +1,148 @@ -#include #include "../include/contact.h" +#include +#include +#include -// Função para adicionar um novo contato à lista. -void addContact(Contact contacts[], int *count) { - printf("Inserir nome do contato: \n"); - scanf("%99s", contacts[*count].name); +void addContact(Contact contacts[], int *count) +{ + printf("\n=== NOVO CONTATO ===\n"); + printf("Nome: "); + fgets(contacts[*count].name, MAX_NAME, stdin); + contacts[*count].name[strcspn(contacts[*count].name, "\n")] = '\0'; + printf("Telefone: "); + fgets(contacts[*count].phone, MAX_PHONE, stdin); + contacts[*count].phone[strcspn(contacts[*count].phone, "\n")] = '\0'; + contacts[*count].id = *count + 1; + (*count)++; + printf("\nContato adicionado.\n"); +} - printf("Inserir telefone do contato: \n"); - scanf("%19s", contacts[*count].phone); +void listContacts(Contact contacts[], int count) +{ + int i; - (*count)++; + if (count == 0) { + printf("\nNenhum contato.\n"); + return; + } + + printf("\n=== CONTATOS ===\n"); + + for (i = 0; i < count; i++) { + printf("\n[%d]\nNome: %s\nTelefone: %s\n", + contacts[i].id, + contacts[i].name, + contacts[i].phone); + } } -// Funçao para listar os contatos armazenados. -void listContacts(Contact contacts[], int count) { +void searchContacts(Contact contacts[], int count) +{ + int i; + int found = 0; + char term[MAX_NAME]; + if (count == 0) { - printf("Nenhum contato encontrado!\n"); + printf("\nNenhum contato.\n"); + return; + } + + printf("\nTermo de busca: "); + fgets(term, MAX_NAME, stdin); + term[strcspn(term, "\n")] = '\0'; + + if (term[0] == '\0') { + printf("\nTermo vazio. Digite um nome ou telefone.\n"); return; } - for (int i = 0; i < count; i++) { - printf("Contato %d:\n", i + 1); - printf("Nome: %s | Telefone: %s\n", contacts[i].name, contacts[i].phone); + printf("\n=== RESULTADO DA BUSCA ===\n"); + for (i = 0; i < count; i++) { + if (strstr(contacts[i].name, term) != NULL || + strstr(contacts[i].phone, term) != NULL) { + printf("\n[%d]\nNome: %s\nTelefone: %s\n", + contacts[i].id, + contacts[i].name, + contacts[i].phone); + found = 1; + } } + + if (!found) + printf("\nNenhum contato encontrado para '%s'.\n", term); } -// As funções removeContact e findContact ainda precisam ser implementadas. +int findContact(Contact contacts[], int count, const char *query) +{ + int i; + char *endptr; + long id; + for (i = 0; i < count; i++) { + if (strcmp(contacts[i].name, query) == 0 || + strcmp(contacts[i].phone, query) == 0) + return i; + } + id = strtol(query, &endptr, 10); + if (*query != '\0' && *endptr == '\0') { + for (i = 0; i < count; i++) { + if (contacts[i].id == id) + return i; + } + } + return -1; +} + +void removeContact(Contact contacts[], int *count) +{ + int i; + int index; + char term[MAX_NAME]; + int confirm; + int c; + + if (*count == 0) { + printf("\nLista vazia.\n"); + return; + } + + printf("\nNome, telefone ou ID do contato: "); + fgets(term, MAX_NAME, stdin); + term[strcspn(term, "\n")] = '\0'; + + if (term[0] == '\0') { + printf("\nTermo vazio. Nenhum contato removido.\n"); + return; + } + + index = findContact(contacts, *count, term); + if (index == -1) { + printf("\nContato nao encontrado.\n"); + return; + } + + printf("\nContato encontrado:\n[%d] %s | %s\n", + contacts[index].id, + contacts[index].name, + contacts[index].phone); + printf("Confirmar remocao? (s/N): "); + confirm = getchar(); + while ((c = getchar()) != '\n' && c != EOF) + ; + if (confirm != 's' && confirm != 'S') { + printf("\nRemocao cancelada.\n"); + return; + } + + for (i = index; i < *count - 1; i++) + contacts[i] = contacts[i + 1]; + + (*count)--; + + for (i = 0; i < *count; i++) + contacts[i].id = i + 1; + + printf("\nContato removido.\n"); +} diff --git a/src/main.c b/src/main.c index 93ee442..9986dfb 100644 --- a/src/main.c +++ b/src/main.c @@ -7,46 +7,55 @@ #define MAX_CONTACTS 100 int main(void) { - Contact contacts[MAX_CONTACTS]; - int count = 0; - int option; - -// Carregar contatos do arquivo ao iniciar o programa. - loadContacts(contacts, &count); - - do { - printf("\nContact Manager\n"); - printf("1. Adicionar contato\n"); - printf("2. Listar contatos\n"); - printf("3. Sair\n"); - printf("Escolha uma opção: "); - if (scanf("%d", &option) != 1) { - fprintf(stderr, "Entrada inválida. Saindo.\n"); - break; - } -// Limpar o buffer de entrada para evitar problemas com scanf. - switch (option) { - case 1: - if (count >= MAX_CONTACTS) { - printf("Limite de contatos atingido.\n"); - } else { - addContact(contacts, &count); - } - break; - case 2: - listContacts(contacts, count); - break; - case 3: - saveContacts(contacts, count); - printf("Contatos salvos. Até logo!\n"); - break; - default: - printf("Opção inválida. Tente novamente.\n"); - break; - } - } while (option != 3); - - return 0; + Contact contacts[MAX_CONTACTS]; + int count = 0; + int option; + int c; + + loadContacts(contacts, &count); + + do { + printf("\n===Contact Manager===\n"); + printf("1. Adicionar contato\n"); + printf("2. Listar contatos\n"); + printf("3. Buscar contato\n"); + printf("4. Remover contato\n"); + printf("5. Sair\n"); + printf("Escolha uma opção: \n"); + + if (scanf("%d", &option) != 1) { + fprintf(stderr, "Entrada inválida. Saindo.\n"); + break; + } + + while ((c = getchar()) != '\n' && c != EOF) + ; + + switch (option) { + case 1: + if (count >= MAX_CONTACTS) + printf("Limite de contatos atingido.\n"); + else + addContact(contacts, &count); + break; + case 2: + listContacts(contacts, count); + break; + case 3: + searchContacts(contacts, count); + break; + case 4: + removeContact(contacts, &count); + break; + case 5: + saveContacts(contacts, count); + printf("Contatos salvos. Até logo!\n"); + break; + default: + printf("Opção inválida. Tente novamente.\n"); + break; + } + } while (option != 5); + + return 0; } -// O programa agora inclui a funcionalidade de carregar e salvar contatos usando as funções definidas em storage.c. -// As funções removeContact e findContact ainda precisam ser implementadas, mas a estrutura básica do programa já está funcional para adicionar e listar contatos. \ No newline at end of file diff --git a/src/storage.c b/src/storage.c index 8131716..2062e7b 100644 --- a/src/storage.c +++ b/src/storage.c @@ -1,40 +1,41 @@ +#include "../include/storage.h" +#include #include #include -#include -#include "../include/storage.h" -// Função para salvar os contatos em um arquivo. void saveContacts(Contact contacts[], int count) { - if (mkdir("data", 0755) != 0 && errno != EEXIST) { - perror("Não foi possível criar diretório data\n"); - return; - } - - FILE *file = fopen("data/contacts.txt", "w"); - if (!file) { - perror("Não foi possível abrir o arquivo de contatos\n"); - return; - } - - for (int i = 0; i < count; i++) { - fprintf(file, "%s,%s\n", contacts[i].name, contacts[i].phone); - } - - fclose(file); + int i; + FILE *file; + + if (mkdir("data", 0755) != 0 && errno != EEXIST) { + perror("Não foi possível criar diretório data"); + return; + } + + file = fopen("data/contacts.txt", "w"); + if (!file) { + perror("Não foi possível abrir o arquivo de contatos"); + return; + } + + for (i = 0; i < count; i++) + fprintf(file, "%s,%s\n", contacts[i].name, contacts[i].phone); + + fclose(file); } -// A função saveContacts agora inclui a criação do diretório "data" se ele não existir, garantindo que o arquivo de contatos possa ser salvo corretamente. void loadContacts(Contact contacts[], int *count) { - FILE *f = fopen("data/contacts.txt", "r"); - if (!f) { - return; - } + FILE *f; + + f = fopen("data/contacts.txt", "r"); + if (!f) + return; - while (fscanf(f, "%99[^,],%19[^\n]\n", contacts[*count].name, contacts[*count].phone) == 2) { - (*count)++; - } + while (fscanf(f, "%99[^,],%19[^\n]\n", contacts[*count].name, + contacts[*count].phone) == 2) { + contacts[*count].id = *count + 1; + (*count)++; + } - fclose(f); + fclose(f); } -// A função loadContacts lê os contatos do arquivo "data/contacts.txt" e os armazena na matriz de contatos, atualizando o contador de contatos. Se o arquivo não existir, a função simplesmente retorna sem fazer nada, permitindo que o programa continue funcionando normalmente. -// As funções saveContacts e loadContacts agora estão implementadas, permitindo que os contatos sejam salvos e carregados de um arquivo, garantindo a persistência dos dados entre as execuções do programa. \ No newline at end of file diff --git a/tests/2026-06-11-add-search-remove.md b/tests/2026-06-11-add-search-remove.md new file mode 100644 index 0000000..226a8f3 --- /dev/null +++ b/tests/2026-06-11-add-search-remove.md @@ -0,0 +1,16 @@ +# Teste 2026-06-11: Adicionar, buscar, remover e persistência + +Data: 2026-06-11 +Objetivo: validar as operações básicas da primeira fase: adicionar, listar, buscar, remover e salvar contatos. +Comando: +```bash +cd src && mkdir -p output && gcc -Wall -Wextra -g3 main.c contact.c storage.c -o output/main && printf '1\nAlice\n1234\n1\nBob\n5678\n2\n3\nAlice\n4\nBob\ns\n5\n' | ./output/main +``` +Saída: +- adicionou Alice e Bob +- listou os dois contatos +- buscou Alice com sucesso +- removeu Bob com confirmação +- salvou e encerrou sem travar +Erros: nenhum +Status: sucesso