C++
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Object-Oriented C++
-
Section 4: Memory Management
-
Section 5: Templates and Generic Programming
-
Section 6: The Standard Template Library
-
Section 7: Modern C++ Features
-
Section 8: Error Handling
-
Section 9: Multithreading
-
Section 10: Operator Overloading and Type Conversion
-
Section 11: Advanced Topics
-
Section 12: Tooling and Build Systems
-
Section 13: Design Patterns in C++
-
Section 14: Interfacing with C and Systems Programming
-
Section 15: Networking and IPC Basics
-
Section 16: Graphics and Game Programming Basics
-
Section 17: The Boost Libraries
-
Section 18: Data Structures and Algorithms in C++
-
Section 19: Practical Projects
-
Section 20: More Concurrency Patterns
-
Section 21: More OOP and Design Practice
-
Section 22: File I/O and Streams
-
Section 23: More Standard Library
-
Section 24: Practice Exercises
-
Section 25: Interview and Algorithm Practice
-
Section 26: Compiler and Language Internals
-
Section 27: GUI and Application Frameworks Overview
-
Section 28: Testing and Quality Practices
-
Section 29: Numerics Library
-
Section 30: Concepts Library (C++20)
-
Section 31: Ranges Library (C++20) In Depth
-
Section 32: More Utility Library
181: Building a Text-Based Inventory Management System
By now, you've got a handle on classes and vectors, but the real test is when you have to glue those concepts together to solve a problem. Today, we're building a text-based inventory management system. I've decided to model this after a small retro game shop—something simple, but it forces us to handle searching, updating, and displaying data effectively.
Defining what an "Item" actually is
I always start by sketching out the data. We don't need a massive class hierarchy here; a simple struct will do. We need a name, a quantity, and a price. Since we're dealing with money, I'll use double for the price, though in a professional financial app, you'd likely use integers representing cents to avoid floating-point errors. For this exercise, double is just fine.
struct Item {
std::string name;
int quantity;
double price;
};
Handling the collection with a vector
I'm going with a std::vector<Item> because it's flexible. We don't know if the shop will have ten items or a thousand. I'll wrap the inventory logic in a class called InventoryManager. This keeps the main function clean and ensures the inventory data isn't just floating around globally, which is a habit you want to break early.
class InventoryManager {
private:
std::vector<Item> items;
public:
void addItem(const std::string& name, int qty, double price) {
items.push_back({name, qty, price});
}
void displayInventory() const {
for (const auto& item : items) {
std::cout << item.name << " | Qty: " << item.quantity
<< " | Price: $" << item.price << "\n";
}
}
};
The "Search and Update" stumble
Now, here is where I usually trip up if I'm rushing. I wanted to add a function to update the quantity of an item. At first, I wrote it like this:
// DON'T DO THIS
void updateQuantity(std::string name, int newQty) {
for (size_t i = 0; i < items.size(); ++i) {
if (items[i].name == name) {
items[i].quantity = newQty;
return;
}
}
// I forgot to handle the case where the item isn't found!
}
I realized that if the user tried to update a "GameBoy" that didn't exist in the list, the function would just silently exit. The user would think the update happened, but the data wouldn't change. It's a classic "silent failure." To fix this, I'll change the function to return a bool. That way, the calling code knows whether to show a success message or an error.
bool updateQuantity(const std::string& name, int newQty) {
for (auto& item : items) {
if (item.name == name) {
item.quantity = newQty;
return true;
}
}
return false;
}
Wiring it into a user loop
Finally, we need a way to actually interact with this. I'll use a while loop and a switch statement. I prefer this over a series of if/else blocks because it's visually cleaner when you have more than two options. You'll notice I'm using std::getline for the item names—never use std::cin >> name if the name might contain a space (like "Super Mario Bros"), or you'll end up with a messy input buffer.
int main() {
InventoryManager myShop;
myShop.addItem("NES Console", 5, 99.99);
myShop.addItem("Sega Genesis", 3, 79.99);
int choice = 0;
while (choice != 4) {
std::cout << "\n1. View 2. Update 3. Add 4. Exit\nChoice: ";
std::cin << choice;
if (choice == 1) {
myShop.displayInventory();
} else if (choice == 2) {
std::string name;
int qty;
std::cout << "Enter item name: ";
std::cin.ignore(); // Clear the newline from the buffer
std::getline(std::cin, name);
std::cout << "Enter new quantity: ";
std::cin << qty;
if (myShop.updateQuantity(name, qty)) {
std::cout << "Update successful!\n";
} else {
std::cout << "Item not found.\n";
}
}
// ... other choices handled similarly
}
return 0;
}📋 Practical Task
Exercise: Implementing a Low-Stock Warning Filter
Right now, the displayInventory method prints everything. In a real warehouse, you only care about what's running out. Your task is to modify the InventoryManager class to include a new method called displayLowStock(int threshold).
- This method should take an integer
thresholdas an argument. - It should iterate through the inventory and only print items whose
quantityis less than or equal to that threshold. - If no items are low on stock, it should print a message saying "All stock levels are healthy."
Once you've written the method, add a new option to the main loop (Option 5) that asks the user for a threshold value and then calls this new function.
There are no comments for now.