Module 00 Solutions
Exercise 00: Megaphone
Section titled “Exercise 00: Megaphone”A simple program to convert input to uppercase.
#include <iostream>#include <cctype>
int main(int argc, char **argv){ // No arguments: print feedback noise if (argc == 1) { std::cout << "* LOUD AND UNBEARABLE FEEDBACK NOISE *" << std::endl; return 0; }
// Convert each argument to uppercase for (int i = 1; i < argc; i++) { for (int j = 0; argv[i][j]; j++) { std::cout << (char)toupper(argv[i][j]); } } std::cout << std::endl;
return 0;}Key Points:
- Use
std::coutinstead ofprintf toupper()returnsint, cast tochar- No spaces between arguments
- Handle the no-argument case
Exercise 01: PhoneBook
Section titled “Exercise 01: PhoneBook”A simple phonebook with ADD, SEARCH, and EXIT commands.
Contact.hpp
Section titled “Contact.hpp”#ifndef CONTACT_HPP#define CONTACT_HPP
#include <string>
class Contact {private: std::string _firstName; std::string _lastName; std::string _nickname; std::string _phoneNumber; std::string _darkestSecret; bool _isEmpty;
public: Contact(); ~Contact();
void setFirstName(const std::string& firstName); void setLastName(const std::string& lastName); void setNickname(const std::string& nickname); void setPhoneNumber(const std::string& phoneNumber); void setDarkestSecret(const std::string& secret); void setIsEmpty(bool isEmpty);
std::string getFirstName() const; std::string getLastName() const; std::string getNickname() const; std::string getPhoneNumber() const; std::string getDarkestSecret() const; bool isEmpty() const;};
#endifPhoneBook.hpp
Section titled “PhoneBook.hpp”#ifndef PHONEBOOK_HPP#define PHONEBOOK_HPP
#include "Contact.hpp"#include <string>
class PhoneBook {private: Contact _contacts[8]; int _currentIndex; int _totalContacts;
std::string _truncate(const std::string& str) const; void _displayContactRow(int index) const; std::string _getInput(const std::string& prompt) const;
public: PhoneBook(); ~PhoneBook();
void addContact(); void searchContacts() const;};
#endifContact.cpp
Section titled “Contact.cpp”#include "Contact.hpp"
Contact::Contact() : _isEmpty(true) {}
Contact::~Contact() {}
void Contact::setFirstName(const std::string& firstName) { _firstName = firstName;}
void Contact::setLastName(const std::string& lastName) { _lastName = lastName;}
void Contact::setNickname(const std::string& nickname) { _nickname = nickname;}
void Contact::setPhoneNumber(const std::string& phoneNumber) { _phoneNumber = phoneNumber;}
void Contact::setDarkestSecret(const std::string& secret) { _darkestSecret = secret;}
void Contact::setIsEmpty(bool isEmpty) { _isEmpty = isEmpty;}
std::string Contact::getFirstName() const { return _firstName; }std::string Contact::getLastName() const { return _lastName; }std::string Contact::getNickname() const { return _nickname; }std::string Contact::getPhoneNumber() const { return _phoneNumber; }std::string Contact::getDarkestSecret() const { return _darkestSecret; }bool Contact::isEmpty() const { return _isEmpty; }PhoneBook.cpp
Section titled “PhoneBook.cpp”#include "PhoneBook.hpp"#include <iostream>#include <iomanip>#include <cstdlib>
PhoneBook::PhoneBook() : _currentIndex(0), _totalContacts(0) {}
PhoneBook::~PhoneBook() {}
std::string PhoneBook::_truncate(const std::string& str) const { if (str.length() > 10) return str.substr(0, 9) + "."; return str;}
void PhoneBook::_displayContactRow(int index) const { std::cout << std::setw(10) << std::right << index << "|"; std::cout << std::setw(10) << std::right << _truncate(_contacts[index].getFirstName()) << "|"; std::cout << std::setw(10) << std::right << _truncate(_contacts[index].getLastName()) << "|"; std::cout << std::setw(10) << std::right << _truncate(_contacts[index].getNickname()) << std::endl;}
std::string PhoneBook::_getInput(const std::string& prompt) const { std::string input;
while (true) { std::cout << prompt; if (!std::getline(std::cin, input)) { std::cout << std::endl; std::exit(0); } if (!input.empty()) break; std::cout << "Field cannot be empty. Please try again." << std::endl; } return input;}
void PhoneBook::addContact() { Contact newContact;
newContact.setFirstName(_getInput("Enter first name: ")); newContact.setLastName(_getInput("Enter last name: ")); newContact.setNickname(_getInput("Enter nickname: ")); newContact.setPhoneNumber(_getInput("Enter phone number: ")); newContact.setDarkestSecret(_getInput("Enter darkest secret: ")); newContact.setIsEmpty(false);
_contacts[_currentIndex] = newContact; _currentIndex = (_currentIndex + 1) % 8; // Circular buffer if (_totalContacts < 8) _totalContacts++;
std::cout << "Contact added successfully!" << std::endl;}
void PhoneBook::searchContacts() const { if (_totalContacts == 0) { std::cout << "PhoneBook is empty." << std::endl; return; }
// Display header std::cout << std::setw(10) << "Index" << "|"; std::cout << std::setw(10) << "First Name" << "|"; std::cout << std::setw(10) << "Last Name" << "|"; std::cout << std::setw(10) << "Nickname" << std::endl; std::cout << std::string(44, '-') << std::endl;
// Display all contacts for (int i = 0; i < _totalContacts; i++) _displayContactRow(i);
// Get index from user std::cout << "Enter index to view details: "; std::string indexStr; if (!std::getline(std::cin, indexStr)) { std::cout << std::endl; return; }
// Validate index if (indexStr.length() != 1 || indexStr[0] < '0' || indexStr[0] > '7') { std::cout << "Invalid index." << std::endl; return; }
int index = indexStr[0] - '0'; if (index >= _totalContacts) { std::cout << "Invalid index." << std::endl; return; }
// Display full contact details std::cout << "First Name: " << _contacts[index].getFirstName() << std::endl; std::cout << "Last Name: " << _contacts[index].getLastName() << std::endl; std::cout << "Nickname: " << _contacts[index].getNickname() << std::endl; std::cout << "Phone Number: " << _contacts[index].getPhoneNumber() << std::endl; std::cout << "Darkest Secret: " << _contacts[index].getDarkestSecret() << std::endl;}Key Points:
- Fixed array of 8 contacts (no dynamic allocation)
- Circular buffer: oldest contact replaced when full
- All attributes private with getters/setters
- Truncate strings > 10 chars with
. - Use
std::setw(10)andstd::rightfor formatting - Handle EOF (Ctrl+D) gracefully
- Reject empty fields
Exercise 02: The Job Of Your Dreams
Section titled “Exercise 02: The Job Of Your Dreams”Reconstruct Account.cpp from the provided Account.hpp and log file. Static members track global state across all accounts.
Account.cpp
Section titled “Account.cpp”#include "Account.hpp"#include <iostream>#include <iomanip>#include <ctime>
// Initialize static membersint Account::_nbAccounts = 0;int Account::_totalAmount = 0;int Account::_totalNbDeposits = 0;int Account::_totalNbWithdrawals = 0;
// Static gettersint Account::getNbAccounts() { return _nbAccounts; }int Account::getTotalAmount() { return _totalAmount; }int Account::getNbDeposits() { return _totalNbDeposits; }int Account::getNbWithdrawals() { return _totalNbWithdrawals; }
// Display timestamp: [YYYYMMDD_HHMMSS]void Account::_displayTimestamp() { std::time_t now = std::time(NULL); std::tm* local = std::localtime(&now);
std::cout << "[" << (local->tm_year + 1900) << std::setfill('0') << std::setw(2) << (local->tm_mon + 1) << std::setfill('0') << std::setw(2) << local->tm_mday << "_" << std::setfill('0') << std::setw(2) << local->tm_hour << std::setfill('0') << std::setw(2) << local->tm_min << std::setfill('0') << std::setw(2) << local->tm_sec << "] ";}
// Display all accounts infovoid Account::displayAccountsInfos() { _displayTimestamp(); std::cout << "accounts:" << _nbAccounts << ";total:" << _totalAmount << ";deposits:" << _totalNbDeposits << ";withdrawals:" << _totalNbWithdrawals << std::endl;}
// Constructor with initial depositAccount::Account(int initial_deposit) : _accountIndex(_nbAccounts), _amount(initial_deposit), _nbDeposits(0), _nbWithdrawals(0) { _nbAccounts++; _totalAmount += initial_deposit;
_displayTimestamp(); std::cout << "index:" << _accountIndex << ";amount:" << _amount << ";created" << std::endl;}
// DestructorAccount::~Account() { _displayTimestamp(); std::cout << "index:" << _accountIndex << ";amount:" << _amount << ";closed" << std::endl;}
// Make a depositvoid Account::makeDeposit(int deposit) { _displayTimestamp(); std::cout << "index:" << _accountIndex << ";p_amount:" << _amount << ";deposit:" << deposit;
_amount += deposit; _nbDeposits++; _totalAmount += deposit; _totalNbDeposits++;
std::cout << ";amount:" << _amount << ";nb_deposits:" << _nbDeposits << std::endl;}
// Make a withdrawal (returns false if insufficient funds)bool Account::makeWithdrawal(int withdrawal) { _displayTimestamp(); std::cout << "index:" << _accountIndex << ";p_amount:" << _amount << ";withdrawal:";
if (withdrawal > _amount) { std::cout << "refused" << std::endl; return false; }
_amount -= withdrawal; _nbWithdrawals++; _totalAmount -= withdrawal; _totalNbWithdrawals++;
std::cout << withdrawal << ";amount:" << _amount << ";nb_withdrawals:" << _nbWithdrawals << std::endl; return true;}
// Check current amountint Account::checkAmount() const { return _amount;}
// Display individual account statusvoid Account::displayStatus() const { _displayTimestamp(); std::cout << "index:" << _accountIndex << ";amount:" << _amount << ";deposits:" << _nbDeposits << ";withdrawals:" << _nbWithdrawals << std::endl;}Key Points:
- Static members must be initialized outside the class (in .cpp file)
_displayTimestamp()uses<ctime>functions:time(),localtime()- Use
std::setfill('0')andstd::setw(2)for zero-padded numbers - Constructor increments
_nbAccountsand adds to_totalAmount makeWithdrawal()returns false and prints “refused” if insufficient funds- Output format must match the log file exactly (semicolon-separated key:value pairs)