Personal Task Automation Tool C++
👤 Sharing: AI
```cpp
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <ctime>
#include <chrono>
#include <iomanip>
#include <algorithm>
#include <filesystem> // Requires C++17 or later. If older, use boost::filesystem or alternative.
#ifdef _WIN32
#include <windows.h> //For sleep on Windows
#else
#include <unistd.h> //For sleep on Linux/macOS
#endif
namespace fs = std::filesystem; //Makes it easier to refer to the namespace.
// Struct to represent a task
struct Task {
std::string description;
std::time_t dueDate;
int priority; // Higher number = higher priority
bool completed;
};
// Function prototypes
void addTask(std::vector<Task>& tasks);
void viewTasks(const std::vector<Task>& tasks);
void markTaskCompleted(std::vector<Task>& tasks);
void deleteTask(std::vector<Task>& tasks);
void saveTasksToFile(const std::vector<Task>& tasks, const std::string& filename);
void loadTasksFromFile(std::vector<Task>& tasks, const std::string& filename);
void sortTasksByPriority(std::vector<Task>& tasks);
void displayMenu();
std::time_t parseDateString(const std::string& dateString);
std::string formatDate(std::time_t time);
void snoozeTask(std::vector<Task>& tasks);
void clearScreen();
int main() {
std::vector<Task> tasks;
std::string filename = "tasks.txt"; // Default filename
// Load tasks from file at the beginning
loadTasksFromFile(tasks, filename);
int choice;
do {
clearScreen();
displayMenu();
std::cout << "Enter your choice: ";
std::cin >> choice;
std::cin.ignore(); // Consume newline
switch (choice) {
case 1:
addTask(tasks);
break;
case 2:
viewTasks(tasks);
break;
case 3:
markTaskCompleted(tasks);
break;
case 4:
deleteTask(tasks);
break;
case 5:
sortTasksByPriority(tasks);
break;
case 6:
snoozeTask(tasks);
break;
case 7:
saveTasksToFile(tasks, filename);
std::cout << "Tasks saved to file.\n";
break;
case 0:
saveTasksToFile(tasks, filename); // Save before exiting
std::cout << "Exiting program.\n";
break;
default:
std::cout << "Invalid choice. Please try again.\n";
}
if (choice != 0) {
std::cout << "Press Enter to continue...";
std::cin.get(); //Wait for the user to press Enter.
}
} while (choice != 0);
return 0;
}
void displayMenu() {
std::cout << "Personal Task Automation Tool\n";
std::cout << "------------------------------\n";
std::cout << "1. Add Task\n";
std::cout << "2. View Tasks\n";
std::cout << "3. Mark Task as Completed\n";
std::cout << "4. Delete Task\n";
std::cout << "5. Sort Tasks by Priority\n";
std::cout << "6. Snooze Task\n";
std::cout << "7. Save Tasks to File\n";
std::cout << "0. Exit\n";
std::cout << "------------------------------\n";
}
void addTask(std::vector<Task>& tasks) {
Task newTask;
std::cout << "Enter task description: ";
std::getline(std::cin, newTask.description);
std::string dateString;
std::cout << "Enter due date (YYYY-MM-DD): ";
std::getline(std::cin, dateString);
newTask.dueDate = parseDateString(dateString);
if (newTask.dueDate == -1) {
std::cout << "Invalid date format. Task added with no due date.\n";
newTask.dueDate = 0; // or some other sensible default
}
std::cout << "Enter priority (1-10, 10 being highest): ";
std::cin >> newTask.priority;
std::cin.ignore(); // Consume newline
newTask.completed = false;
tasks.push_back(newTask);
std::cout << "Task added successfully.\n";
}
void viewTasks(const std::vector<Task>& tasks) {
if (tasks.empty()) {
std::cout << "No tasks to display.\n";
return;
}
std::cout << "------------------------------\n";
for (size_t i = 0; i < tasks.size(); ++i) {
std::cout << i + 1 << ". ";
std::cout << "Description: " << tasks[i].description << "\n";
if (tasks[i].dueDate != 0) {
std::cout << " Due Date: " << formatDate(tasks[i].dueDate) << "\n";
} else {
std::cout << " Due Date: N/A\n";
}
std::cout << " Priority: " << tasks[i].priority << "\n";
std::cout << " Completed: " << (tasks[i].completed ? "Yes" : "No") << "\n";
std::cout << "------------------------------\n";
}
}
void markTaskCompleted(std::vector<Task>& tasks) {
viewTasks(tasks); // Show the tasks so the user can choose
if (tasks.empty()) {
return;
}
int taskNumber;
std::cout << "Enter the number of the task to mark as completed: ";
std::cin >> taskNumber;
std::cin.ignore(); // Consume newline
if (taskNumber >= 1 && taskNumber <= tasks.size()) {
tasks[taskNumber - 1].completed = true;
std::cout << "Task marked as completed.\n";
} else {
std::cout << "Invalid task number.\n";
}
}
void deleteTask(std::vector<Task>& tasks) {
viewTasks(tasks); // Show the tasks so the user can choose
if (tasks.empty()) {
return;
}
int taskNumber;
std::cout << "Enter the number of the task to delete: ";
std::cin >> taskNumber;
std::cin.ignore(); // Consume newline
if (taskNumber >= 1 && taskNumber <= tasks.size()) {
tasks.erase(tasks.begin() + taskNumber - 1);
std::cout << "Task deleted.\n";
} else {
std::cout << "Invalid task number.\n";
}
}
void saveTasksToFile(const std::vector<Task>& tasks, const std::string& filename) {
std::ofstream outputFile(filename);
if (outputFile.is_open()) {
for (const auto& task : tasks) {
outputFile << task.description << "\n";
outputFile << task.dueDate << "\n";
outputFile << task.priority << "\n";
outputFile << task.completed << "\n";
}
outputFile.close();
} else {
std::cerr << "Unable to open file for writing.\n";
}
}
void loadTasksFromFile(std::vector<Task>& tasks, const std::string& filename) {
std::ifstream inputFile(filename);
Task tempTask;
if (inputFile.is_open()) {
while (std::getline(inputFile, tempTask.description)) {
std::string dueDateStr, priorityStr, completedStr;
std::getline(inputFile, dueDateStr);
std::getline(inputFile, priorityStr);
std::getline(inputFile, completedStr);
try {
tempTask.dueDate = std::stoll(dueDateStr);
tempTask.priority = std::stoi(priorityStr);
tempTask.completed = (completedStr == "1"); //Convert string to bool
} catch (const std::invalid_argument& e) {
std::cerr << "Error parsing task data. Skipping task.\n";
continue; //Skip the rest of the loop and go to the next task
} catch (const std::out_of_range& e) {
std::cerr << "Error parsing task data (out of range). Skipping task.\n";
continue;
}
tasks.push_back(tempTask);
}
inputFile.close();
} else {
//If file doesn't exist, it's not necessarily an error. Just means no tasks saved yet.
//std::cerr << "Unable to open file for reading. Starting with an empty task list.\n";
std::cout << "No existing task file found. Starting with an empty task list.\n"; //Less alarming message.
}
}
// Custom comparison function for sorting tasks by priority
bool compareTasksByPriority(const Task& a, const Task& b) {
return a.priority > b.priority; // Sort in descending order (highest priority first)
}
void sortTasksByPriority(std::vector<Task>& tasks) {
std::sort(tasks.begin(), tasks.end(), compareTasksByPriority);
std::cout << "Tasks sorted by priority.\n";
}
std::time_t parseDateString(const std::string& dateString) {
std::tm t{};
std::istringstream ss(dateString);
ss >> std::get_time(&t, "%Y-%m-%d");
if (ss.fail()) {
return -1; // Indicate parsing failure
}
return mktime(&t);
}
std::string formatDate(std::time_t time) {
std::tm t = *std::localtime(&time);
std::ostringstream oss;
oss << std::put_time(&t, "%Y-%m-%d");
return oss.str();
}
void snoozeTask(std::vector<Task>& tasks) {
viewTasks(tasks);
if (tasks.empty()) {
return;
}
int taskNumber;
std::cout << "Enter the number of the task to snooze: ";
std::cin >> taskNumber;
std::cin.ignore();
if (taskNumber >= 1 && taskNumber <= tasks.size()) {
int snoozeMinutes;
std::cout << "Enter snooze duration in minutes: ";
std::cin >> snoozeMinutes;
std::cin.ignore();
tasks[taskNumber - 1].dueDate += snoozeMinutes * 60; // Add minutes in seconds
std::cout << "Task snoozed. New due date: " << formatDate(tasks[taskNumber - 1].dueDate) << "\n";
} else {
std::cout << "Invalid task number.\n";
}
}
void clearScreen() {
#ifdef _WIN32
system("cls"); // For Windows
#else
system("clear"); // For Linux/macOS
#endif
}
```
👁️ Viewed: 122
Comments