CS-210 Guide

{/* Hidden */}

Student Created Guide

Section 1: Introduction to the Chada Tech Clock Project

This section introduces the CS-210 Project One, a simulated real-world task for aspiring junior developers. You'll learn about the project's goals, the core requirements of creating a dual 12-hour and 24-hour clock application in C++, and how your work will be evaluated. Understanding these foundational elements is the first step to success.

1.1. Understanding the Core Task: The Chada Tech Clocks

The Chada Tech interview scenario requires the development of a dual clock display system. This system is intended to meet international standard ISO 8601 by providing both 12-hour and 24-hour time formats. Key aspects include simultaneous display, user input handling for time manipulation, and adherence to secure and efficient C++ coding practices. It is important to note that this assignment is a simulation of clock functionality; it does not require display of the local time zone, real-time ticking, or synchronization with system time. The emphasis is on program logic, object-oriented design, and code quality.

1.2. Deconstructing the Project Requirements and Rubric

A thorough understanding of the "Chada Tech Clocks Functional Requirements" document and the "Project One Rubric" is paramount. The functional requirements will detail specific behaviors, such as the format of the clock displays, the menu options, and how the clocks should respond to user input. The rubric outlines the criteria for assessment, including:

  • Follows Flowchart Diagram: The application’s sequence of functions must align with the provided flowchart logic.
  • Code Modularization: Code should be organized into functions, minimizing the amount of code within the main() function. (20 points)
  • Code Execution (Clock Displays, Menu Functionality, Responds to User Input): The program must correctly display both clocks in the specified formats, present a functional menu, and accurately manipulate the clocks based on user selections. (Combined 55 points)
  • Industry Standard Best Practices: This includes in-line comments, appropriate naming conventions, and overall code clarity. (15 points, opportunity to exceed)

Adherence to these requirements and rubric criteria will be central to achieving a successful project outcome.

πŸ”— Connect with Coding United

This project guide is brought to you by a Coding United member! Explore our resources and join our community:

Section 2: Laying the Groundwork: Essential C++ Concepts

Before diving into coding, it's crucial to have a solid grasp of fundamental C++ concepts. This section outlines the building blocks you'll need for the clock project, from basic input/output operations to the principles of object-oriented programming. Each concept plays a vital role in constructing a functional and well-structured application.

Concept Relevance to Project Key Aspects to Understand
Basic Input/Output Getting initial time from user, reading menu choices, displaying clocks and menu. std::cin, std::cout, <iostream> header, stream extraction (>>) and insertion (<<) operators.
Control Flow Implementing program logic from flowchart: main loop, menu decision making, time update conditions. if-else, switch, while loops.
Functions Modularizing code (e.g., for displaying menu, getting input, updating time, displaying clocks), minimizing main(). Declaration (prototype), definition, parameters, return types, function calls.
Basic Time Concepts Representing and formatting time components (hours, minutes, seconds, AM/PM). Integer variables for H, M, S; <ctime> for struct tm and strftime (optional for formatting).
Object-Oriented Prog. Designing Clock class(es) to encapsulate time data and operations. Classes, objects, member variables, member functions (methods), constructors, encapsulation.
Headers & Source Files Organizing class declarations and definitions into separate .h and .cpp files. #include, header guards (#ifndef/#define/#endif or #pragma once).

2.1. Communicating with the User: Basic Input/Output (<iostream>)

The <iostream> header file is fundamental for console-based applications, providing tools for standard input and output operations. The primary objects used will be std::cout for displaying information (like the clocks and menu) to the screen and std::cin for reading user input (like the initial time settings and menu choices).

std::cout uses the insertion operator (<<) to send data to the output stream. For example:

#include <iostream>

int main() {
    std::cout << "Welcome to the Chada Tech Clock Project!" << std::endl;
    return 0;
}

std::cin uses the extraction operator (>>) to get data from the input stream (usually the keyboard) and store it in variables. For instance, to get a user's menu choice:

#include <iostream>

//...
int main() {
    int userChoice;
    std::cout << "Enter your choice: ";
    std::cin >> userChoice; // Reads an integer from input
    std::cout << "You entered: " << userChoice << std::endl;
    return 0;
}

It is important to be aware that when std::cin is used to read into a std::string, it typically stops reading at the first whitespace character (space, tab, or newline). While this project primarily involves integer input for menu choices and time components, this behavior is a key characteristic of std::cin. For integer input, std::cin will attempt to parse a number; if non-numeric characters are entered, the stream can enter an error state, which may require explicit handling for more robust applications (discussed later in input validation).

2.2. Controlling the Flow: if-else, switch, and Loops for Program Logic

Control flow statements are essential for dictating the order in which code executes, enabling decision-making and repetition, which are critical for implementing the program's flowchart logic.

These structures allow the program to execute different blocks of code based on whether a condition is true or false. They are vital for logic such as determining AM/PM, handling time rollovers, or validating user input ranges.

if (hour == 0) {
    // Handle midnight case for 12-hour clock
} else if (hour == 12) {
    // Handle noon case for 12-hour clock
} else {
    // Handle other hours
}

A switch statement provides a clean way to select one of many code blocks to be executed based on the value of an expression, typically an integer or character. This is ideal for handling the user's menu choice. Each case corresponds to a possible choice, and the break statement is crucial to prevent "fall-through". A default case can handle invalid inputs.

// Assuming 'userChoice' is an int
switch (userChoice) {
    case 1:
        // Call function to add hour
        break; // Exits the switch statement
    case 2:
        // Call function to add minute
        break;
    // ... other cases ...
    default:
        std::cout << "Invalid choice. Please try again." << std::endl;
}

The while loop repeatedly executes a block of statements as long as a given condition remains true. This is perfectly suited for the main program loop, which should continue until the user selects "Exit Program".

bool programIsRunning = true;
while (programIsRunning) {
    // Display clocks
    // Display menu
    // Get user input
    // Process input
    // If user chooses to exit, set programIsRunning = false;
}

The condition is checked before each iteration. Ensure actions within the loop can eventually make the condition false to avoid infinite loops.

2.3. Organizing Your Code: The Power of Functions

Functions allow breaking down a program into manageable, reusable pieces. Each function should perform a single task, enhancing readability and maintainability. The rubric emphasizes minimizing code in main().

  • Declaration (Prototype): Informs compiler of function's name, return type, parameters. E.g., void displayUserMenu();
  • Definition: The actual code block of the function.
  • Parameters: Input values for the function.
  • Return Type: Value returned by function (void if none).
// Prototype
void displayUserMenu();

// Definition
void displayUserMenu() {
    std::cout << "******************************\n";
    // ... menu items ...
    std::cout << "******************************\n";
}

Using functions makes main() an orchestrator, calling other functions for specific tasks.

2.4. A Quick Look at Time in C++: <ctime> and struct tm (and <chrono>)

C++ offers ways to work with time. <ctime> (C-style) provides struct tm to hold time components (seconds, minutes, hours, etc.) and functions like strftime for formatting.

struct tm {
  int tm_sec;   // seconds (0-61)
  int tm_min;   // minutes (0-59)
  int tm_hour;  // hours (0-23)
  //... other members
};

<chrono> is a more modern, type-safe library. For this project, manually incrementing integers for time components is simpler and aligns with example solutions. <ctime> might be used optionally for formatting.

Section 3: The Heart of the Matter: Designing Your Clock's Brain

This section dives into the core logic of your clock application. You'll explore how to represent time internally, implement the mechanics for adding seconds, minutes, and hours (including handling rollovers), and master the specific formatting requirements for both 12-hour and 24-hour displays.

3.1. Representing Time: Storing Hours, Minutes, and Seconds

Simple integer variables (int hours;, int minutes;, int seconds;) are suitable for storing time components within your clock class(es).

For the 12-hour clock, an AM/PM indicator is needed. This can be a bool isPM; or an enum AmPmState { AM, PM };. The 24-hour clock (0-23 hours) doesn't need this. Using separate classes for 12-hour and 24-hour clocks is a good OOP approach.

3.2. The Tick-Tock Logic: Adding Seconds, Minutes, and Hours

Incrementing time units and handling rollovers is critical.

  • Adding a Second (addSecond()): Increment seconds. If seconds reach 60, reset to 0 and call addMinute().
  • Adding a Minute (addMinute()): Increment minutes. If minutes reach 60, reset to 0 and call addHour().
  • Adding an Hour (addHour()):
    • 24-Hour Clock: If hours reach 24, reset to 0.
    • 12-Hour Clock: More complex. Incrementing from 11 AM/PM to 12 PM/AM requires toggling AM/PM. Hours typically range 1-12 for display, though internal storage might be 0-11.

Conceptual addSecond method:

void Clock::addSecond() {
    seconds++;
    if (seconds >= 60) {
        seconds = 0;
        addMinute(); // Cascade update
    }
}

3.3. Mastering Time Formats

Correct formatting (leading zeros, AM/PM) is key.

Hours: 00-23, Minutes: 00-59, Seconds: 00-59. Leading zeros required (e.g., "09:05:03").

Hours: 01-12, Minutes/Seconds: 00-59. Leading zeros required. AM/PM designation.

Key Points for 12 o'clock:

  • Midnight: 12:00:00 AM (00:00:00 in 24-hour)
  • Noon: 12:00:00 PM (12:00:00 in 24-hour)

Simple modulo 12 arithmetic is insufficient for 24-to-12 hour conversion due to these cases. Special logic is needed for hours 0 (midnight) and 12 (noon).

If managing time internally in 24-hour format (hour24 from 0-23):

  1. If hour24 == 0 (Midnight): hour12 = 12, meridiem = "AM".
  2. If hour24 >= 1 && hour24 <= 11 (Morning): hour12 = hour24, meridiem = "AM".
  3. If hour24 == 12 (Noon): hour12 = 12, meridiem = "PM".
  4. If hour24 >= 13 && hour24 <= 23 (Afternoon/Evening): hour12 = hour24 - 12, meridiem = "PM".

Section 4: Building with Blueprints: Object-Oriented Programming for Clocks

The project requires an Object-Oriented Programming (OOP) approach. This section explains why OOP is beneficial for this project and guides you through designing your Clock class(es), including how to structure your C++ header (.h) and source (.cpp) files effectively.

4.1. Why OOP? Benefits for Your Project

OOP revolves around "objects" that bundle data and methods.

  • Encapsulation: Bundles data (time components) and methods (addHour, getFormattedTime) into a class, protecting data and simplifying use.
  • Abstraction: Hides complex implementation details (like rollover logic), exposing only essential features.
  • Modularity and Reusability: Classes act as blueprints, promoting modular design.

4.2. Designing Your Clock Class (or classes)

A recommended approach is using an abstract base class (Time) with derived classes (Clock12, Clock24).

Time (Abstract Base Class)
Pure Virtual Functions:
virtual void addOneHour() = 0;
virtual void addOneMinute() = 0;
virtual void addOneSecond() = 0;
virtual std::string getFormattedTime() const = 0;
↓ (Inherits) ↓
Clock12 (Derived)
Members: h, m, s, meridiem
Overrides: addOneHour(), getFormattedTime(), etc.
Clock24 (Derived)
Members: h, m, s
Overrides: addOneHour(), getFormattedTime(), etc.

Member Variables (Data): int for hours, minutes, seconds. For Clock12, an enum AmPmState { AM, PM }; is good for clarity.

Member Functions (Methods):

  • Constructors: To initialize objects (set initial time).
  • Time Manipulation: addHour(), addMinute(), addSecond().
  • Formatting: getFormattedTime() returning a std::string.

4.3. Structuring Your Project Files: .h (Declarations) and .cpp (Implementations)

Separate class declarations from definitions.

  • Header Files (.h or .hpp): Contain class declarations, function prototypes. Must use include guards (#ifndef/#define/#endif or #pragma once) to prevent redefinition errors.
  • Source Files (.cpp): Contain definitions (implementations) of member functions. Include corresponding header file. main() is typically in its own .cpp file.

Example Clock.h (with #pragma once):

// Clock.h
#pragma once
#include <string>
enum class AmPmState { AM, PM };
class Clock12 {
public:
    Clock12(int h, int m, int s, AmPmState ampm);
    void addHour();
    std::string getFormattedTime() const;
private:
    int hour, minute, second;
    AmPmState meridiem;
};
// ... Clock24 declaration ...

Example Clock.cpp:

// Clock.cpp
#include "Clock.h"
#include <iomanip> 
#include <sstream>  
Clock12::Clock12(int h, int m, int s, AmPmState ampm) : hour(h), minute(m), second(s), meridiem(ampm) {}
void Clock12::addHour() { /* ... 12-hour logic ... */ }
std::string Clock12::getFormattedTime() const {
    std::ostringstream oss;
    // oss << std::setfill('0') << std::setw(2) << (hour == 0 ? 12 : hour);
    return oss.str();
}
// ... other definitions ...

Include guards are essential to prevent "redeclaration" errors when headers are included multiple times.

Section 5: Bringing Your Clocks to Life: Implementation Steps

This section walks you through the practical steps of coding your clock application, translating the design and flowchart into functional C++ code. You'll cover setting the initial time, implementing the main program loop, crafting the user menu, processing input, and displaying the clocks as required.

5.1. Setting Initial Time (User Input)

Prompt user for initial hours, minutes, seconds. Validate input (e.g., hours 0-23, min/sec 0-59). Use these values to initialize clock objects.

int initialHour, initialMinute, initialSecond;
std::cout << "Enter initial hour (0-23): ";
std::cin >> initialHour;
// ... validate and read minutes, seconds ...
// Clock24 clock24(initialHour, initialMinute, initialSecond);
// Clock12 clock12(convertedH12, initialMinute, initialSecond, ampm_val);

5.2. Implementing the Program Flowchart: The Main Loop

Use a while loop controlled by a boolean flag (e.g., bool keepRunning = true;).

Inside the loop:

  1. Display Clocks
  2. Display Menu
  3. Get User Input (validated choice)
  4. Process Choice (switch statement):
    • Add Hour: Call addHour() on both clocks.
    • Add Minute: Call addMinute() on both clocks.
    • Add Second: Call addSecond() on both clocks.
    • Exit: Set keepRunning = false; or call exit(0);.
    • Default: Handle invalid choice.

The flowchart can be visualized as follows:

START Program
↓
Get User Input for Initial Time
↓
LOOP (while running)
↓
Display Clocks & Menu
↓
Get User Menu Choice
↓
IF Add Hour?
↳ (Yes)
Add Hour & Display Time
↓ (No or After Yes)
IF Add Minute?
↳ (Yes)
Add Minute & Display Time
↓ (No or After Yes)
IF Add Second?
↳ (Yes)
Add Second & Display Time
↓ (No or After Yes)
IF EXIT?
↳ (Yes)
Exit Program (set running to false)
↑ (No to Exit: Back to LOOP Start)
END LOOP
↓
END Program

5.3. Crafting the User Menu

Display the menu exactly as specified. A function displayMenu() is ideal.

void displayMenu() {
    std::cout << "******************************\n";
    std::cout << "* 1- Add One Hour            *\n";
    std::cout << "* 2- Add One Minute          *\n";
    std::cout << "* 3- Add One Second          *\n";
    std::cout << "* 4- Exit Program            *\n";
    std::cout << "******************************\n";
    std::cout << "Enter your choice: ";
}
Menu Option Displayed User Input (Integer) Action Performed
* 1- Add One Hour * 1 Add one hour to both clocks; refresh display.
* 2- Add One Minute * 2 Add one minute to both clocks; refresh display.
* 3- Add One Second * 3 Add one second to both clocks; refresh display.
* 4- Exit Program * 4 Terminate the program.
Any other input N/A Display error message; re-prompt.

5.4. Processing User Input: Making Choices Work

Read user's menu choice. Validate input type (is it a number?) and range (1-4).

int choice; std::cin >> choice;
if (std::cin.fail()) { /* ... handle error ... */ } 
else if (choice < 1 || choice > 4) { /* ... handle error ... */ } 
else { /* Process valid choice */ }

5.5. The Grand Display: Showing Two Clocks Simultaneously

Display clocks side-by-side with asterisk borders.

****************************** ******************************
* 12-Hour Clock            * * 24-Hour Clock            *
* 03:22:01 PM              * * 15:22:01                 *
****************************** ******************************

Leading Zeros: Use <iomanip>: std::setfill('0') << std::setw(2).

strftime from <ctime> can format time.

//#include 
#include 

int main() {
    time_t t = time(nullptr);
    char buffer[100];
    strftime(buffer, sizeof(buffer), "Current date and time: %Y-%m-%d %H:%M:%S", localtime(&t));
    std::cout << buffer << std::endl;
    return 0;
}

Section 6: Polishing Your Code: Professionalism and Best Practices

Meeting functional requirements is just one part of software development...

6.1. Code Modularization: Keeping main() Lean

main() should orchestrate. Example functions:

  • void getInitialTime(int& h, int& m, int& s);
  • void displayMenu();
  • int getUserChoice();
  • void displayClocks(const Clock12& c12, const Clock24& c24);
  • void processUserChoice(int choice, Clock12& c12, Clock24& c24, bool& running);

6.2. The Art of Comments

Explain the "why." File and function headers are important.

// File Header Example:
// Name: [Your Name]
// Course: CS-210 - Project One
// Date: [Current Date]
// Description: Main application file for the Chada Tech Clocks.
// Function Header Example:
// Processes the user's menu selection and updates clocks.
// choice: The validated integer choice from the user.
// c12: Reference to the 12-hour clock object.
// c24: Reference to the 24-hour clock object.
// running: Reference to the main loop control flag.
void processUserChoice(int choice, Clock12& c12, Clock24& c24, bool& running) { /* ... */ }

6.3. Naming Conventions

Use consistent, meaningful names (PascalCase, camelCase, etc.).

  • Classes/Structs: PascalCase (e.g., ClockTime).
  • Functions/Methods: camelCase (e.g., displayCurrentTime) or snake_case.
  • Variables: camelCase (e.g., currentUserInput) or snake_case.
  • Constants: ALL_CAPS_SNAKE_CASE (e.g., SECONDS_IN_MINUTE).

6.4. "Secure and Efficient C++ Code"

Focus on input validation and straightforward logic.

  • Security (Basic): Input Validation (std::cin.fail(), etc.).
  • Efficiency (Basic): Sensible logic, avoid unnecessary computations.

Section 7: Final Checks and Submission

Before submitting your project, it's vital to conduct thorough testing and review your work against the project requirements and rubric. This final polish ensures your application is complete, functional, and meets all expectations for professionalism and code quality.

7.1. Testing Your Application

Test all functional requirements and edge cases (midnight/noon rollovers, invalid inputs). Initial Time Input: Prompting, acceptance, validation.
Clock Display: Simultaneous, correct 12/24h formats, leading zeros, asterisk borders.
Menu Functionality: Correct display, accepts choices 1-4, handles invalid input.
Time Manipulation (for each menu option - Add Second, Minute, Hour):
Both clocks update.
Correct rollover logic (seconds, minutes, hours, AM/PM). Test edge cases like 11:59:59 AM -> 12:00:00
PM, 23:59:59 -> 00:00:00.
Exit Program: Option 4 terminates cleanly.

7.2. Reviewing Against the Rubric

Self-assess your project against all rubric criteria: Flowchart, Modularization, Execution, Best Practices.
Follows Flowchart Diagram?
Code Modularization (lean main(), effective functions)?
Code Execution (displays, menu, input response correct)?
Industry Standard Best Practices (comments, naming, readability)?

7.3. Preparing Your Files for Submission

Submit a ZIP file with all .cpp and .h files. Ensure file headers are complete.

Use this interactive checklist to ensure you've met all functional requirements. Your progress here is not saved.

General:

Clock Functionality:

User Menu and Interaction:

Appendix

This appendix provides supplementary information that may be useful for your project, including a quick reference for strftime format codes and the full C++ example code from the original guidance document.

A.1. Quick Reference: strftime Format Codes

SpecifierReplaced byExample
%HHour (24h)14
%IHour (12h)02
%MMinute55
%SSecond02
%pAM/PMPM
%r12-hour time02:55:02 pm
%THH:MM:SS (24h)14:55:02
%XLocale's time14:55:02

The following is the complete C++ code example provided in Appendix A.1 of the original CS-210 Project One Guidance document. Note that this example uses global variables for simplicity and does not fully implement the class-based OOP structure required by the project, but serves as a procedural illustration of the core logic.

#include <iostream>
#include <string>
#include <vector>
#include <iomanip>
#include <sstream>
#include <limits>

// Forward declaration for the display function
void displayClocks(int h12, int m12, int s12, bool isPm12, int h24, int m24, int s24);
void displayMenu();
int getValidatedChoice(int min, int max);
// void clearScreen(); // Not fully implemented in example

// Global variables for time
int currentHour12 = 12, currentMinute12 = 0, currentSecond12 = 0;
bool isPM12 = false; // false for AM, true for PM
int currentHour24 = 0, currentMinute24 = 0, currentSecond24 = 0;

// Function to add one second to both clocks
void addSecond() {
    // 24-hour clock logic
    currentSecond24++;
    if (currentSecond24 >= 60) {
        currentSecond24 = 0;
        currentMinute24++;
        if (currentMinute24 >= 60) {
            currentMinute24 = 0;
            currentHour24++;
            if (currentHour24 >= 24) {
                currentHour24 = 0;
            }
        }
    }

    // 12-hour clock logic
    currentSecond12++;
    if (currentSecond12 >= 60) {
        currentSecond12 = 0;
        currentMinute12++;
        if (currentMinute12 >= 60) {
            currentMinute12 = 0;
            currentHour12++;
            if (currentHour12 == 12) {
                isPM12 = !isPM12;
            }
            if (currentHour12 > 12) {
                currentHour12 = 1;
            }
        }
    }
}

// Function to add one minute to both clocks
void addMinute() {
    // 24-hour clock logic
    currentMinute24++;
    if (currentMinute24 >= 60) {
        currentMinute24 = 0;
        currentHour24++;
        if (currentHour24 >= 24) {
            currentHour24 = 0;
        }
    }

    // 12-hour clock logic
    currentMinute12++;
    if (currentMinute12 >= 60) {
        currentMinute12 = 0;
        currentHour12++;
        if (currentHour12 == 12) {
            isPM12 = !isPM12;
        }
        if (currentHour12 > 12) {
            currentHour12 = 1;
        }
    }
}

// Function to add one hour to both clocks
void addHour() {
    // 24-hour clock logic
    currentHour24++;
    if (currentHour24 >= 24) {
        currentHour24 = 0;
    }

    // 12-hour clock logic
    currentHour12++;
    if (currentHour12 == 12) {
        isPM12 = !isPM12;
    }
    if (currentHour12 > 12) {
        currentHour12 = 1;
    }
}

// Helper function to format a number with leading zero if needed
std::string formatTwoDigits(int n) {
    std::ostringstream oss;
    oss << std::setfill('0') << std::setw(2) << n;
    return oss.str();
}

// Function to display both clocks side-by-side
void displayClocks(int h12, int m12, int s12, bool isPm12, int h24, int m24, int s24) {
    std::string border = "******************************";
    std::string separator = "   ";

    std::string time12Str = formatTwoDigits(h12) + ":" +
                            formatTwoDigits(m12) + ":" +
                            formatTwoDigits(s12) + (isPm12 ? " PM" : " AM");

    std::string time24Str = formatTwoDigits(h24) + ":" +
                            formatTwoDigits(m24) + ":" +
                            formatTwoDigits(s24);

    std::string label12 = "12-Hour Clock";
    std::string label24 = "24-Hour Clock";

    int p_l12_t = border.length() - 2 - label12.length(); int p_l12_l = p_l12_t / 2; int p_l12_r = p_l12_t - p_l12_l;
    int p_l24_t = border.length() - 2 - label24.length(); int p_l24_l = p_l24_t / 2; int p_l24_r = p_l24_t - p_l24_l;
    int p_t12_t = border.length() - 2 - time12Str.length(); int p_t12_l = p_t12_t / 2; int p_t12_r = p_t12_t - p_t12_l;
    int p_t24_t = border.length() - 2 - time24Str.length(); int p_t24_l = p_t24_t / 2; int p_t24_r = p_t24_t - p_t24_l;

    std::cout << border << separator << border << std::endl;
    std::cout << "*" << std::string(p_l12_l, ' ') << label12 << std::string(p_l12_r, ' ') << "*"
              << separator
              << "*" << std::string(p_l24_l, ' ') << label24 << std::string(p_l24_r, ' ') << "*" << std::endl;
    std::cout << "*" << std::string(p_t12_l, ' ') << time12Str << std::string(p_t12_r, ' ') << "*"
              << separator
              << "*" << std::string(p_t24_l, ' ') << time24Str << std::string(p_t24_r, ' ') << "*" << std::endl;
    std::cout << border << separator << border << std::endl;
}

// Function to display the user menu
void displayMenu() {
    std::cout << "\n******************************\n";
    std::cout << "* 1- Add One Hour            *\n";
    std::cout << "* 2- Add One Minute          *\n";
    std::cout << "* 3- Add One Second          *\n";
    std::cout << "* 4- Exit Program            *\n";
    std::cout << "******************************\n";
}
int getValidatedChoice(int min, int max) {
    int choice;
    while (true) {
        std::cout << "Enter your choice: ";
        std::cin >> choice;
        if (std::cin.good() && choice >= min && choice <= max) {
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            return choice;
        } else {
            std::cout << "Invalid input. Please enter a number between " << min << " and " << max << "." << std::endl;
            std::cin.clear();
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        }
    }
}
// int main() { /* ... */ } // Original example main commented out for brevity