C++: Prática: Sistema de Agenda

Última atualização: 2026-08-26

Na aula 50, aprendemos sobre testes unitários.

Agora, vamos construir nosso primeiro projeto prático abrangente — um sistema de agenda.

Este projeto integrará todo o conhecimento que você aprendeu até agora.


1. Requisitos do Projeto

(1) 1.1 Requisitos Funcionais

Funcionalidade Descrição
Adicionar contato Inserir nome, telefone, email
Excluir contato Excluir por nome ou telefone
Modificar contato Atualizar informações
Buscar contato Pesquisar por nome ou telefone
Exibir todos Listar todos os contatos
Salvar/Carregar Persistir em arquivo

(2) 1.2 Design de Classes

TEXT 📖 Somente leitura
Contact
  - name, phone, email

AddressBook
  - vector<Contact> contacts
  - add, remove, update, find, display
  - save, load


2. Classe Contact

(1) 2.1 Definição da Classe Contact

TEXT 📖 Somente leitura
#include <iostream>
#include <string>
#include <fstream>

class Contact {
private:
	std::string name;
	std::string phone;
	std::string email;

public:
	Contact() = default;
	Contact(const std::string& name, const std::string& phone, const std::string& email)
	: name(name), phone(phone), email(email) {}
	
	// Getter
	std::string getName() const { return name; }
	std::string getPhone() const { return phone; }
	std::string getEmail() const { return email; }
	
	// Setter
	void setName(const std::string& n) { name = n; }
	void setPhone(const std::string& p) { phone = p; }
	void setEmail(const std::string& e) { email = e; }
	
	// Exibir
	void display() const {
		std::cout << "Name: " << name << std::endl;
		std::cout << "Phone: " << phone << std::endl;
		std::cout << "Email: " << email << std::endl;
		std::cout << "-------------------" << std::endl;
	}
	
	// Serializar (salvar em arquivo)
	void save(std::ofstream& file) const {
		file << name << "," << phone << "," << email << std::endl;
	}
	
	// Desserializar (carregar de arquivo)
	static Contact load(std::ifstream& file) {
		Contact c;
		std::getline(file, c.name, ',');
		std::getline(file, c.phone, ',');
		std::getline(file, c.email);
		return c;
	}
};


3. Classe Agenda

(1) 3.1 Definição da Classe AddressBook

▶ Exemplo 1: Usando Contêineres STL (Dificuldade ⭐)

CPP 📖 Somente leitura
#include <vector>
#include <algorithm>

class AddressBook {
private:
	std::vector<Contact> contacts;

public:
	// Adicionar contato
	void addContact(const Contact& c) {
		contacts.push_back(c);
		std::cout << "Added successfully!" << std::endl;
	}
	
	// Buscar contato (por nome)
	Contact* findByName(const std::string& name) {
		for (auto& c : contacts) {
			if (c.getName() == name) {
				return &c;
			}
		}
		return nullptr;
	}
	
	// Excluir contato (por nome)
	bool removeByName(const std::string& name) {
		auto it = std::remove_if(contacts.begin(), contacts.end(),
			[&name](const Contact& c) {
				return c.getName() == name;
			});
		
		if (it != contacts.end()) {
			contacts.erase(it, contacts.end());
			std::cout << "Deleted successfully!" << std::endl;
			return true;
		}
		
		std::cout << "Contact not found: " << name << std::endl;
		return false;
	}
	
	// Exibir todos os contatos
	void displayAll() const {
		if (contacts.empty()) {
			std::cout << "Address book is empty" << std::endl;
			return;
		}
		
		for (const auto& c : contacts) {
			c.display();
		}
	}
	
	// Salvar em arquivo
	void saveToFile(const std::string& filename) const {
		std::ofstream file(filename);
		if (!file) {
			std::cerr << "Cannot open file" << std::endl;
			return;
		}
		
		for (const auto& c : contacts) {
			c.save(file);
		}
		
		file.close();
		std::cout << "Saved successfully!" << std::endl;
	}
	
	// Carregar de arquivo
	void loadFromFile(const std::string& filename) {
		std::ifstream file(filename);
		if (!file) {
			std::cerr << "Cannot open file" << std::endl;
			return;
		}
		
		contacts.clear(); // Limpar dados existentes
		
		std::string line;
		while (file.peek() != EOF) {
			contacts.push_back(Contact::load(file));
		}
		
		file.close();
		std::cout << "Loaded successfully!" << std::endl;
	}
};
65 linhas de lógica (limite de 40, somente leitura)

Saída:

TEXT 📖 Somente leitura
Added successfully!
Deleted successfully!
Contact not found:
Address book is empty
Saved successfully!
Loaded successfully!


4. Menu Principal

(1) 4.1 Implementação do Menu

TEXT 📖 Somente leitura
void showMenu() {
### ▶ Exemplo 2: Prática Básica de Programação (Dificuldade ⭐)

	std::cout << "\n===== Address Book Management System =====" << std::endl;
	std::cout << "1. Add contact" << std::endl;
	std::cout << "2. Delete contact" << std::endl;
	std::cout << "3. Find contact" << std::endl;
	std::cout << "4. Display all contacts" << std::endl;
	std::cout << "5. Save" << std::endl;
	std::cout << "6. Load" << std::endl;
	std::cout << "0. Exit" << std::endl;
	std::cout << "==========================================" << std::endl;
	std::cout << "Choose: ";
}

int main() {
	AddressBook book;
	int choice;
	
	do {
		showMenu();
		std::cin >> choice;
		
		switch (choice) {
		case 1: {
			std::string name, phone, email;
			std::cout << "Name: ";
			std::cin >> name;
			std::cout << "Phone: ";
			std::cin >> phone;
			std::cout << "Email: ";
			std::cin >> email;
			book.addContact(Contact(name, phone, email));
			break;
		}
		case 2: {
			std::string name;
			std::cout << "Name: ";
			std::cin >> name;
			book.removeByName(name);
			break;
		}
		case 3: {
			std::string name;
			std::cout << "Name: ";
			std::cin >> name;
			Contact* c = book.findByName(name);
			if (c) {
				c->display();
			} else {
				std::cout << "Not found" << std::endl;
			}
			break;
		}
		case 4:
			book.displayAll();
			break;
		case 5: {
			book.saveToFile("contacts.txt");
			break;
		}
		case 6: {
			book.loadFromFile("contacts.txt");
			break;
		}
		case 0:
			std::cout << "Goodbye!" << std::endl;
			break;
		default:
			std::cout << "Invalid choice" << std::endl;
		}
	} while (choice != 0);
	
	return 0;
}


5. Sugestões de Extensão

(1) 5.1 Extensões de Funcionalidade

Funcionalidade Dificuldade
Buscar por telefone
Modificar contato ⭐⭐
Ordenar por nome ⭐⭐
Importar/Exportar CSV ⭐⭐⭐
GUI ⭐⭐⭐⭐


❓ Exercícios

(1) Exercício Básico (Dificuldade ⭐)

Adicione um recurso de "busca por telefone" à agenda.

(2) Exercício Intermediário (Dificuldade ⭐⭐)

Adicione um recurso de "modificar contato" à agenda.

(3) Exercício Desafio (Dificuldade ⭐⭐⭐)

Refatore a agenda usando std::map para melhorar a eficiência de busca.


▶ Exemplo 3: Definição de Struct Contact (Dificuldade ⭐)

CPP
#include <iostream>
#include <string>

struct Contact {
    std::string name;
    std::string phone;
    std::string email;

    void display() const {
        std::cout << "Name: " << name << std::endl;
        std::cout << "Phone: " << phone << std::endl;
        std::cout << "Email: " << email << std::endl;
    }
};

int main() {
    Contact c1 = {"Zhang San", "13800138000", "zhangsan@example.com"};
    Contact c2 = {"Li Si", "13900139000", "lisi@example.com"};

    c1.display();
    std::cout << "---" << std::endl;
    c2.display();

    return 0;
}
▶ Experimente

Saída:

TEXT 📖 Somente leitura
Name:
Phone:
Email:
---

❓ Perguntas Frequentes

P: Por que usar vector em vez de arrays? R: vector redimensiona automaticamente, então você não precisa saber o número de elementos antecipadamente. O tamanho de um array deve ser determinado em tempo de compilação, enquanto vector pode crescer e encolher flexivelmente em tempo de execução. P: Por que usar um struct para informações de contato em vez de múltiplos arrays? R: Structs empacotam dados relacionados juntos, tornando a lógica mais clara. Com múltiplos arrays, operações de adição/exclusão são propensas a erros (ex.: excluir um nome mas esquecer de excluir o telefone). P: No que devo prestar atenção com I/O de arquivos? R: ① Verifique se o arquivo abriu com sucesso (is_open); ② Feche após escrever (close()); ③ Use eof() ou good() em loops de leitura para evitar loops infinitos; ④ Use tratamento de exceções para garantir que os arquivos sejam fechados corretamente.

📖 Resumo

Ponto de Conhecimento Aplicação
Orientação a Objetos Classes Contact e AddressBook
STL vector para armazenar contatos
Operações com Arquivos Salvar/Carregar
Processamento de Strings Analisar CSV

📝 Exercícios

  1. Básico (Dificuldade ⭐): Execute o programa de agenda, adicione 3 contatos (nome, telefone, grupo) e visualize a exibição. Tente usar o recurso "editar" para modificar as informações de um contato.

  2. Intermediário (Dificuldade ⭐⭐): Adicione um recurso de "contato favorito" à agenda — adicione um campo bool isFavorite ao struct e marque contatos favoritos com [★] ao exibir a lista.

  3. Desafio (Dificuldade ⭐⭐⭐): Implemente um recurso de "busca difusa": após o usuário inserir uma palavra-chave, corresponda todos os contatos cujos nomes contenham a palavra-chave e exiba-os. Se a entrada estiver vazia, mostre todos os contatos. Suporte correspondência insensível a maiúsculas/minúsculas.


Próxima aula: Prática: Banco de Dados Simples (#52)

Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%