🎯 Recommended Samples
Balanced sample collections from various categories for you to explore
Windows Error Handling C++ Samples
Windows C++ error handling examples including exception handling, logging, and parameter validation
💻 Exception Handling cpp
🟢 simple
⭐⭐
Implement try-catch exception handling with custom exception classes for Windows applications
⏱️ 20 min
🏷️ cpp, exception, error handling, windows
Prerequisites:
Basic C++, Exception handling concepts
// Windows C++ Exception Handling Examples
#include <iostream>
#include <string>
#include <vector>
#include <exception>
#include <stdexcept>
#include <windows.h>
// 1. Custom Exception Classes
class WindowsException : public std::exception {
private:
DWORD m_errorCode;
std::string m_message;
std::string m_function;
std::string m_file;
int m_line;
public:
WindowsException(DWORD errorCode, const std::string& message,
const std::string& function, const std::string& file, int line)
: m_errorCode(errorCode), m_message(message), m_function(function),
m_file(file), m_line(line) {
m_description = formatDescription();
}
const char* what() const noexcept override {
return m_description.c_str();
}
DWORD getErrorCode() const { return m_errorCode; }
const std::string& getFunction() const { return m_function; }
const std::string& getFile() const { return m_file; }
int getLine() const { return m_line; }
private:
std::string m_description;
std::string formatDescription() const {
char buffer[256];
sprintf_s(buffer, "Error 0x%08X in %s (%s:%d): %s",
m_errorCode, m_function.c_str(), m_file.c_str(), m_line, m_message.c_str());
return buffer;
}
};
// Macro for throwing exceptions with file/line info
#define THROW_WINDOWS_ERROR(msg, errorCode) \
throw WindowsException(errorCode, msg, __FUNCTION__, __FILE__, __LINE__)
#define THROW_IF_FAILED(hr, msg) \
if (FAILED(hr)) { \
THROW_WINDOWS_ERROR(msg, hr); \
}
// 2. File Operation Exception
class FileException : public std::runtime_error {
public:
enum class ErrorType {
NotFound,
AccessDenied,
AlreadyExists,
InvalidPath,
ReadError,
WriteError
};
private:
ErrorType m_errorType;
std::string m_filePath;
public:
FileException(ErrorType type, const std::string& filePath)
: std::runtime_error(formatMessage(type, filePath)),
m_errorType(type), m_filePath(filePath) {}
ErrorType getErrorType() const { return m_errorType; }
const std::string& getFilePath() const { return m_filePath; }
private:
static std::string formatMessage(ErrorType type, const std::string& path) {
std::string typeName;
switch (type) {
case ErrorType::NotFound: typeName = "File not found"; break;
case ErrorType::AccessDenied: typeName = "Access denied"; break;
case ErrorType::AlreadyExists: typeName = "File already exists"; break;
case ErrorType::InvalidPath: typeName = "Invalid path"; break;
case ErrorType::ReadError: typeName = "Read error"; break;
case ErrorType::WriteError: typeName = "Write error"; break;
}
return typeName + ": " + path;
}
};
// 3. Validation Exception
class ValidationException : public std::runtime_error {
public:
enum class ErrorType {
NullPointer,
EmptyString,
OutOfRange,
InvalidFormat,
NegativeValue,
ExceedsMaximum
};
private:
ErrorType m_errorType;
std::string m_parameterName;
public:
ValidationException(ErrorType type, const std::string& paramName)
: std::runtime_error(formatMessage(type, paramName)),
m_errorType(type), m_parameterName(paramName) {}
ErrorType getErrorType() const { return m_errorType; }
const std::string& getParameterName() const { return m_parameterName; }
private:
static std::string formatMessage(ErrorType type, const std::string& param) {
std::string typeName;
switch (type) {
case ErrorType::NullPointer: typeName = "Null pointer"; break;
case ErrorType::EmptyString: typeName = "Empty string"; break;
case ErrorType::OutOfRange: typeName = "Out of range"; break;
case ErrorType::InvalidFormat: typeName = "Invalid format"; break;
case ErrorType::NegativeValue: typeName = "Negative value"; break;
case ErrorType::ExceedsMaximum: typeName = "Exceeds maximum"; break;
}
return "Validation failed [" + typeName + "]: " + param;
}
};
// 4. Network Exception
class NetworkException : public std::runtime_error {
public:
enum class ErrorType {
ConnectionFailed,
Timeout,
DnsError,
HttpError,
SslError
};
private:
ErrorType m_errorType;
int m_errorCode;
public:
NetworkException(ErrorType type, int errorCode, const std::string& message)
: std::runtime_error(message), m_errorType(type), m_errorCode(errorCode) {}
ErrorType getErrorType() const { return m_errorType; }
int getErrorCode() const { return m_errorCode; }
};
// 5. Database Exception
class DatabaseException : public std::runtime_error {
private:
std::string m_sqlState;
int m_nativeError;
public:
DatabaseException(const std::string& message, const std::string& sqlState, int nativeError)
: std::runtime_error(message), m_sqlState(sqlState), m_nativeError(nativeError) {}
const std::string& getSQLState() const { return m_sqlState; }
int getNativeError() const { return m_nativeError; }
};
// 6. Exception Handler with Logging
class ExceptionHandler {
public:
static void handleException(const std::exception& e) {
std::cerr << "\n=== Exception Caught ===" << std::endl;
std::cerr << "Type: " << typeid(e).name() << std::endl;
std::cerr << "Message: " << e.what() << std::endl;
// Try to handle specific exception types
try {
dynamic_cast<const WindowsException&>(e);
std::cerr << "This is a Windows exception" << std::endl;
} catch (...) {}
try {
const FileException& fe = dynamic_cast<const FileException&>(e);
std::cerr << "File: " << fe.getFilePath() << std::endl;
std::cerr << "Error Type: " << static_cast<int>(fe.getErrorType()) << std::endl;
} catch (...) {}
}
static void handleUnknownException() {
std::cerr << "\n=== Unknown Exception Caught ===" << std::endl;
std::cerr << "An unknown exception was caught" << std::endl;
}
static std::string getLastErrorString() {
DWORD errorCode = GetLastError();
if (errorCode == 0) {
return "No error";
}
LPSTR messageBuffer = nullptr;
size_t size = FormatMessageA(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr,
errorCode,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPSTR)&messageBuffer,
0,
nullptr
);
std::string message(messageBuffer, size);
LocalFree(messageBuffer);
return message;
}
};
// 7. RAII Exception-Safe Wrapper
class ExceptionSafeFile {
private:
HANDLE m_hFile;
std::string m_filename;
public:
ExceptionSafeFile(const std::string& filename, bool forRead = true)
: m_hFile(INVALID_HANDLE_VALUE), m_filename(filename) {
DWORD access = forRead ? GENERIC_READ : GENERIC_WRITE;
DWORD disposition = forRead ? OPEN_EXISTING : CREATE_ALWAYS;
m_hFile = CreateFileA(
filename.c_str(),
access,
FILE_SHARE_READ,
nullptr,
disposition,
FILE_ATTRIBUTE_NORMAL,
nullptr
);
if (m_hFile == INVALID_HANDLE_VALUE) {
DWORD error = GetLastError();
FileException::ErrorType errorType;
if (error == ERROR_FILE_NOT_FOUND) {
errorType = FileException::ErrorType::NotFound;
} else if (error == ERROR_ACCESS_DENIED) {
errorType = FileException::ErrorType::AccessDenied;
} else {
errorType = FileException::ErrorType::InvalidPath;
}
throw FileException(errorType, filename);
}
std::cout << "File opened successfully: " << filename << std::endl;
}
~ExceptionSafeFile() {
close();
}
void close() {
if (m_hFile != INVALID_HANDLE_VALUE) {
CloseHandle(m_hFile);
m_hFile = INVALID_HANDLE_VALUE;
std::cout << "File closed: " << m_filename << std::endl;
}
}
HANDLE getHandle() const { return m_hFile; }
};
// 8. Try-Catch Examples
void demonstrateTryCatch() {
std::cout << "\n--- Basic Try-Catch ---" << std::endl;
try {
// Code that might throw
std::string str = "test";
if (str.empty()) {
throw ValidationException(
ValidationException::ErrorType::EmptyString,
"str"
);
}
std::cout << "String validation passed" << std::endl;
} catch (const ValidationException& e) {
ExceptionHandler::handleException(e);
} catch (const std::exception& e) {
ExceptionHandler::handleException(e);
}
}
// 9. Nested Try-Catch
void demonstrateNestedTryCatch() {
std::cout << "\n--- Nested Try-Catch ---" << std::endl;
try {
std::cout << "Outer try block" << std::endl;
try {
std::cout << "Inner try block" << std::endl;
// Simulate error
throw std::runtime_error("Inner error");
} catch (const std::exception& inner) {
std::cout << "Inner catch: " << inner.what() << std::endl;
// Re-throw to outer handler
throw;
}
} catch (const std::exception& outer) {
std::cout << "Outer catch: " << outer.what() << std::endl;
}
}
// 10. Exception Specifications and noexcept
class SafeOperation {
public:
// Function that doesn't throw exceptions
void safeFunction() noexcept {
std::cout << "This function guarantees not to throw" << std::endl;
// If an exception occurs, program will terminate
}
// Function with exception specification
void riskyFunction() throw(std::runtime_error) {
throw std::runtime_error("This function only throws runtime_error");
}
void demonstrateNoExcept() {
safeFunction();
try {
riskyFunction();
} catch (const std::runtime_error& e) {
std::cout << "Caught expected error: " << e.what() << std::endl;
}
}
};
// 11. Multiple Catch Blocks
void demonstrateMultipleCatches() {
std::cout << "\n--- Multiple Catch Blocks ---" << std::endl;
try {
// Simulate different types of errors
int choice = 2; // Change to test different exceptions
switch (choice) {
case 1:
throw std::invalid_argument("Invalid argument");
case 2:
throw std::runtime_error("Runtime error");
case 3:
throw std::out_of_range("Out of range");
case 4:
throw "C-style string exception";
default:
std::cout << "No exception" << std::endl;
}
} catch (const std::invalid_argument& e) {
std::cout << "Invalid argument: " << e.what() << std::endl;
} catch (const std::runtime_error& e) {
std::cout << "Runtime error: " << e.what() << std::endl;
} catch (const std::out_of_range& e) {
std::cout << "Out of range: " << e.what() << std::endl;
} catch (const std::exception& e) {
std::cout << "Standard exception: " << e.what() << std::endl;
} catch (...) {
std::cout << "Unknown exception caught" << std::endl;
}
}
// 12. Exception Propagation
void level3Function() {
throw std::runtime_error("Error in level 3");
}
void level2Function() {
level3Function();
}
void level1Function() {
try {
level2Function();
} catch (const std::exception& e) {
std::cout << "Caught at level 1: " << e.what() << std::endl;
throw; // Re-throw
}
}
void demonstrateExceptionPropagation() {
std::cout << "\n--- Exception Propagation ---" << std::endl;
try {
level1Function();
} catch (const std::exception& e) {
std::cout << "Caught at main: " << e.what() << std::endl;
}
}
// 13. Standard Exception Usage
void divideNumbers(int a, int b) {
if (b == 0) {
throw std::invalid_argument("Division by zero is not allowed");
}
double result = static_cast<double>(a) / b;
std::cout << a << " / " << b << " = " << result << std::endl;
}
void demonstrateStandardExceptions() {
std::cout << "\n--- Standard Exceptions ---" << std::endl;
try {
divideNumbers(10, 2);
divideNumbers(10, 0); // This will throw
} catch (const std::invalid_argument& e) {
std::cout << "Caught: " << e.what() << std::endl;
}
}
// Main demonstration
int main() {
std::cout << "=== Windows C++ Exception Handling Examples ===" << std::endl;
// 1. Basic try-catch
demonstrateTryCatch();
// 2. Nested try-catch
demonstrateNestedTryCatch();
// 3. Multiple catch blocks
demonstrateMultipleCatches();
// 4. Exception propagation
demonstrateExceptionPropagation();
// 5. Standard exceptions
demonstrateStandardExceptions();
// 6. Safe operations
std::cout << "\n--- Exception-Safe Operations ---" << std::endl;
try {
ExceptionSafeFile file("test_exception.txt", false);
std::cout << "File operation completed" << std::endl;
} catch (const FileException& e) {
ExceptionHandler::handleException(e);
}
// 7. Noexcept demonstration
std::cout << "\n--- Noexcept Demonstration ---" << std::endl;
SafeOperation safeOp;
safeOp.demonstrateNoExcept();
std::cout << "\n=== All Exception Handling Examples Completed ===" << std::endl;
return 0;
}
💻 Parameter Validation cpp
🟢 simple
⭐⭐⭐
Validate function parameters including null checks, range validation, and custom validation rules
⏱️ 20 min
🏷️ cpp, validation, error handling, windows
Prerequisites:
Basic C++, Exception handling
// Windows C++ Parameter Validation Examples
#include <iostream>
#include <string>
#include <vector>
#include <stdexcept>
#include <regex>
#include <algorithm>
#include <windows.h>
// 1. Basic Validation Functions
class ParameterValidator {
public:
// Null pointer validation
template<typename T>
static void notNull(T* ptr, const std::string& paramName = "pointer") {
if (ptr == nullptr) {
throw std::invalid_argument(paramName + " cannot be null");
}
}
// String validation
static void notEmpty(const std::string& str, const std::string& paramName = "string") {
if (str.empty()) {
throw std::invalid_argument(paramName + " cannot be empty");
}
}
static void maxLength(const std::string& str, size_t maxLen, const std::string& paramName = "string") {
if (str.length() > maxLen) {
throw std::invalid_argument(paramName + " exceeds maximum length of " + std::to_string(maxLen));
}
}
static void minLength(const std::string& str, size_t minLen, const std::string& paramName = "string") {
if (str.length() < minLen) {
throw std::invalid_argument(paramName + " is shorter than minimum length of " + std::to_string(minLen));
}
}
// Numeric validation
static void notNegative(int value, const std::string& paramName = "value") {
if (value < 0) {
throw std::invalid_argument(paramName + " cannot be negative (got: " + std::to_string(value) + ")");
}
}
static void inRange(int value, int min, int max, const std::string& paramName = "value") {
if (value < min || value > max) {
throw std::out_of_range(paramName + " must be between " + std::to_string(min) +
" and " + std::to_string(max) + " (got: " + std::to_string(value) + ")");
}
}
static void positive(double value, const std::string& paramName = "value") {
if (value <= 0.0) {
throw std::invalid_argument(paramName + " must be positive (got: " + std::to_string(value) + ")");
}
}
// Array/Container validation
template<typename T>
static void notEmpty(const std::vector<T>& vec, const std::string& paramName = "vector") {
if (vec.empty()) {
throw std::invalid_argument(paramName + " cannot be empty");
}
}
template<typename T>
static void inBounds(size_t index, const std::vector<T>& vec, const std::string& indexName = "index") {
if (index >= vec.size()) {
throw std::out_of_range(indexName + " out of bounds (size: " +
std::to_string(vec.size()) + ", index: " + std::to_string(index) + ")");
}
}
static void maxSize(const std::vector<int>& vec, size_t max, const std::string& paramName = "vector") {
if (vec.size() > max) {
throw std::invalid_argument(paramName + " exceeds maximum size of " + std::to_string(max));
}
}
};
// 2. File Path Validation
class PathValidator {
public:
static bool isValidPath(const std::string& path) {
if (path.empty()) {
return false;
}
// Check for invalid characters
const std::string invalidChars = "<>"|?*";
for (char c : invalidChars) {
if (path.find(c) != std::string::npos) {
return false;
}
}
return true;
}
static void validatePath(const std::string& path, const std::string& paramName = "path") {
if (!isValidPath(path)) {
throw std::invalid_argument(paramName + " contains invalid characters: " + path);
}
}
static void validateFileExtension(const std::string& filename,
const std::vector<std::string>& allowedExtensions,
const std::string& paramName = "filename") {
size_t dotPos = filename.find_last_of('.');
if (dotPos == std::string::npos) {
throw std::invalid_argument(paramName + " has no file extension");
}
std::string ext = filename.substr(dotPos);
std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
for (const auto& allowedExt : allowedExtensions) {
std::string lowerAllowed = allowedExt;
std::transform(lowerAllowed.begin(), lowerAllowed.end(), lowerAllowed.begin(), ::tolower);
if (ext == lowerAllowed || ext == "." + lowerAllowed) {
return; // Valid extension
}
}
throw std::invalid_argument(paramName + " has invalid extension: " + ext);
}
};
// 3. String Format Validation
class FormatValidator {
public:
static void validateEmail(const std::string& email) {
// Basic email validation regex
std::regex emailRegex(R"([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,})");
if (!std::regex_match(email, emailRegex)) {
throw std::invalid_argument("Invalid email format: " + email);
}
}
static void validatePhoneNumber(const std::string& phone) {
// Remove common formatting characters
std::string cleaned = phone;
cleaned.erase(std::remove(cleaned.begin(), cleaned.end(), '('), cleaned.end());
cleaned.erase(std::remove(cleaned.begin(), cleaned.end(), ')'), cleaned.end());
cleaned.erase(std::remove(cleaned.begin(), cleaned.end(), '-'), cleaned.end());
cleaned.erase(std::remove(cleaned.begin(), cleaned.end(), ' '), cleaned.end());
// Check if all remaining characters are digits
if (!std::all_of(cleaned.begin(), cleaned.end(), ::isdigit)) {
throw std::invalid_argument("Invalid phone number format: " + phone);
}
// Check length (typical US phone numbers)
if (cleaned.length() != 10 && cleaned.length() != 11) {
throw std::invalid_argument("Invalid phone number length: " + phone);
}
}
static void validateURL(const std::string& url) {
std::regex urlRegex(R"(https?://[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}(/.*)?)");
if (!std::regex_match(url, urlRegex)) {
throw std::invalid_argument("Invalid URL format: " + url);
}
}
static void validateIPAddress(const std::string& ip) {
std::regex ipRegex(R"(^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$)");
if (!std::regex_match(ip, ipRegex)) {
throw std::invalid_argument("Invalid IP address format: " + ip);
}
}
static void validateDateFormat(const std::string& date) {
// Check YYYY-MM-DD format
std::regex dateRegex(R"(^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$)");
if (!std::regex_match(date, dateRegex)) {
throw std::invalid_argument("Invalid date format (expected YYYY-MM-DD): " + date);
}
}
};
// 4. Business Rule Validation
class BusinessValidator {
public:
static void validateAge(int age, const std::string& paramName = "age") {
ParameterValidator::inRange(age, 0, 150, paramName);
}
static void validateUsername(const std::string& username) {
ParameterValidator::notEmpty(username, "username");
ParameterValidator::minLength(username, 3, "username");
ParameterValidator::maxLength(username, 20, "username");
// Username must contain only alphanumeric characters and underscore
std::regex usernameRegex(R"(^[a-zA-Z0-9_]+$)");
if (!std::regex_match(username, usernameRegex)) {
throw std::invalid_argument("Username can only contain letters, numbers, and underscores");
}
}
static void validatePassword(const std::string& password) {
ParameterValidator::minLength(password, 8, "password");
bool hasUpper = false, hasLower = false, hasDigit = false, hasSpecial = false;
for (char c : password) {
if (isupper(c)) hasUpper = true;
else if (islower(c)) hasLower = true;
else if (isdigit(c)) hasDigit = true;
else if (ispunct(c)) hasSpecial = true;
}
if (!hasUpper) {
throw std::invalid_argument("Password must contain at least one uppercase letter");
}
if (!hasLower) {
throw std::invalid_argument("Password must contain at least one lowercase letter");
}
if (!hasDigit) {
throw std::invalid_argument("Password must contain at least one digit");
}
if (!hasSpecial) {
throw std::invalid_argument("Password must contain at least one special character");
}
}
static void validatePort(int port) {
ParameterValidator::inRange(port, 1, 65535, "port");
}
static void validatePercentage(double value, const std::string& paramName = "percentage") {
if (value < 0.0 || value > 100.0) {
throw std::invalid_argument(paramName + " must be between 0 and 100 (got: " +
std::to_string(value) + ")");
}
}
};
// 5. Batch Validation
class BatchValidator {
private:
std::vector<std::string> m_errors;
public:
template<typename Func>
void validateAll(const std::vector<std::pair<Func, std::string>>& validations) {
for (const auto& [validation, description] : validations) {
try {
validation();
} catch (const std::exception& e) {
m_errors.push_back(description + ": " + e.what());
}
}
}
bool hasErrors() const {
return !m_errors.empty();
}
const std::vector<std::string>& getErrors() const {
return m_errors;
}
void throwIfErrors() const {
if (!m_errors.empty()) {
std::string message = "Validation failed:\n";
for (const auto& error : m_errors) {
message += " - " + error + "\n";
}
throw std::invalid_argument(message);
}
}
};
// 6. Precondition and Postcondition Checks
class Contract {
public:
template<typename T>
static void requires(T* ptr, const std::string& message = "Precondition failed") {
if (ptr == nullptr) {
throw std::runtime_error(message);
}
}
static void requires(bool condition, const std::string& message = "Precondition failed") {
if (!condition) {
throw std::runtime_error(message);
}
}
static void ensures(bool condition, const std::string& message = "Postcondition failed") {
if (!condition) {
throw std::runtime_error(message);
}
}
};
// 7. Validation Helper Macros
#define VALIDATE_NOT_NULL(ptr) ParameterValidator::notNull(ptr, #ptr)
#define VALIDATE_NOT_EMPTY(str) ParameterValidator::notEmpty(str, #str)
#define VALIDATE_NOT_NEGATIVE(val) ParameterValidator::notNegative(val, #val)
#define VALIDATE_RANGE(val, min, max) ParameterValidator::inRange(val, min, max, #val)
#define VALIDATE_EMAIL(email) FormatValidator::validateEmail(email)
#define VALIDATE_PATH(path) PathValidator::validatePath(path, #path)
// 8. Practical Usage Examples
class UserService {
public:
struct User {
std::string username;
std::string email;
std::string password;
int age;
};
void createUser(const User& user) {
std::cout << "\n--- Creating User ---" << std::endl;
// Validate all fields
BatchValidator validator;
validator.validateAll({
{[&]() { BusinessValidator::validateUsername(user.username); }, "username"},
{[&]() { FormatValidator::validateEmail(user.email); }, "email"},
{[&]() { BusinessValidator::validatePassword(user.password); }, "password"},
{[&]() { BusinessValidator::validateAge(user.age); }, "age"}
});
validator.throwIfErrors();
std::cout << "User validation passed!" << std::endl;
std::cout << "Username: " << user.username << std::endl;
std::cout << "Email: " << user.email << std::endl;
std::cout << "Age: " << user.age << std::endl;
}
};
class NetworkConfig {
public:
std::string host;
int port;
std::string url;
int timeout;
void validate() const {
Contract::requires(!host.empty(), "Host cannot be empty");
Contract::requires(port > 0, "Port must be positive");
BusinessValidator::validatePort(port);
FormatValidator::validateIPAddress(host);
ParameterValidator::positive(timeout, "timeout");
}
};
// 9. Function with Preconditions and Postconditions
std::vector<int> processArray(const std::vector<int>& input, int multiplier) {
// Preconditions
VALIDATE_NOT_EMPTY(input);
VALIDATE_NOT_NEGATIVE(multiplier);
std::vector<int> result;
for (int value : input) {
result.push_back(value * multiplier);
}
// Postcondition
Contract::ensures(result.size() == input.size(), "Output size must match input size");
return result;
}
// Main demonstration
int main() {
std::cout << "=== Windows C++ Parameter Validation Examples ===" << std::endl;
// 1. Basic validation
std::cout << "\n--- Basic Validation ---" << std::endl;
try {
ParameterValidator::notEmpty("test", "myString");
ParameterValidator::inRange(50, 0, 100, "score");
ParameterValidator::notNegative(42, "count");
std::cout << "All validations passed!" << std::endl;
} catch (const std::exception& e) {
std::cerr << "Validation error: " << e.what() << std::endl;
}
// 2. Format validation
std::cout << "\n--- Format Validation ---" << std::endl;
try {
FormatValidator::validateEmail("[email protected]");
FormatValidator::validatePhoneNumber("123-456-7890");
FormatValidator::validateURL("https://example.com");
FormatValidator::validateIPAddress("192.168.1.1");
std::cout << "All format validations passed!" << std::endl;
} catch (const std::exception& e) {
std::cerr << "Format error: " << e.what() << std::endl;
}
// 3. User creation with validation
std::cout << "\n--- User Creation with Validation ---" << std::endl;
UserService userService;
try {
UserService::User user;
user.username = "john_doe";
user.email = "[email protected]";
user.password = "SecurePass123";
user.age = 25;
userService.createUser(user);
} catch (const std::exception& e) {
std::cerr << "User creation failed: " << e.what() << std::endl;
}
// 4. Contract usage
std::cout << "\n--- Contract Usage ---" << std::endl;
try {
std::vector<int> data = {1, 2, 3, 4, 5};
std::vector<int> result = processArray(data, 2);
std::cout << "Array processed successfully" << std::endl;
} catch (const std::exception& e) {
std::cerr << "Contract error: " << e.what() << std::endl;
}
// 5. Path validation
std::cout << "\n--- Path Validation ---" << std::endl;
try {
PathValidator::validatePath("C:\\Valid\\Path\\file.txt");
PathValidator::validateFileExtension("document.pdf", {".pdf", ".doc", ".docx"});
std::cout << "Path validation passed!" << std::endl;
} catch (const std::exception& e) {
std::cerr << "Path error: " << e.what() << std::endl;
}
std::cout << "\n=== All Parameter Validation Examples Completed ===" << std::endl;
return 0;
}
💻 Logging System cpp
🟡 intermediate
⭐⭐⭐
Implement a comprehensive logging system with multiple log levels, file logging, and rotation
⏱️ 30 min
🏷️ cpp, logging, error handling, windows
Prerequisites:
Intermediate C++, File I/O
// Windows C++ Logging System Examples
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <chrono>
#include <iomanip>
#include <vector>
#include <mutex>
#include <windows.h>
// 1. Log Level Enumeration
enum class LogLevel {
TRACE = 0,
DEBUG = 1,
INFO = 2,
WARNING = 3,
ERROR = 4,
CRITICAL = 5,
OFF = 6
};
std::string logLevelToString(LogLevel level) {
switch (level) {
case LogLevel::TRACE: return "TRACE";
case LogLevel::DEBUG: return "DEBUG";
case LogLevel::INFO: return "INFO";
case LogLevel::WARNING: return "WARNING";
case LogLevel::ERROR: return "ERROR";
case LogLevel::CRITICAL: return "CRITICAL";
case LogLevel::OFF: return "OFF";
default: return "UNKNOWN";
}
}
// 2. Logger Class
class Logger {
private:
static Logger* s_instance;
static std::mutex s_mutex;
LogLevel m_minLevel;
std::vector<std::ofstream*> m_fileStreams;
std::mutex m_logMutex;
bool m_consoleOutput;
bool m_includeTimestamp;
bool m_includeThreadId;
Logger()
: m_minLevel(LogLevel::INFO)
, m_consoleOutput(true)
, m_includeTimestamp(true)
, m_includeThreadId(false) {
}
std::string getCurrentTimestamp() const {
auto now = std::chrono::system_clock::now();
auto time = std::chrono::system_clock::to_time_t(now);
std::stringstream ss;
ss << std::put_time(std::localtime(&time), "%Y-%m-%d %H:%M:%S");
return ss.str();
}
DWORD getCurrentThreadId() const {
return GetCurrentThreadId();
}
public:
static Logger& getInstance() {
std::lock_guard<std::mutex> lock(s_mutex);
if (s_instance == nullptr) {
s_instance = new Logger();
}
return *s_instance;
}
Logger(const Logger&) = delete;
Logger& operator=(const Logger&) = delete;
void setMinLevel(LogLevel level) {
m_minLevel = level;
}
void enableConsoleOutput(bool enable) {
m_consoleOutput = enable;
}
void enableTimestamp(bool enable) {
m_includeTimestamp = enable;
}
void enableThreadId(bool enable) {
m_includeThreadId = enable;
}
bool addLogFile(const std::string& filename) {
std::lock_guard<std::mutex> lock(m_logMutex);
std::ofstream* file = new std::ofstream(filename, std::ios::app);
if (!file->is_open()) {
delete file;
return false;
}
m_fileStreams.push_back(file);
return true;
}
void closeAllLogFiles() {
std::lock_guard<std::mutex> lock(m_logMutex);
for (auto* file : m_fileStreams) {
if (file->is_open()) {
file->close();
}
delete file;
}
m_fileStreams.clear();
}
void log(LogLevel level, const std::string& message, const char* file = nullptr, int line = 0) {
if (level < m_minLevel) {
return;
}
std::lock_guard<std::mutex> lock(m_logMutex);
std::stringstream logEntry;
// Add timestamp
if (m_includeTimestamp) {
logEntry << "[" << getCurrentTimestamp() << "] ";
}
// Add log level
logEntry << "[" << logLevelToString(level) << "] ";
// Add thread ID
if (m_includeThreadId) {
logEntry << "[TID:" << getCurrentThreadId() << "] ";
}
// Add message
logEntry << message;
// Add file and line if provided
if (file && line > 0) {
logEntry << " (" << file << ":" << line << ")";
}
logEntry << std::endl;
std::string logString = logEntry.str();
// Output to console
if (m_consoleOutput) {
// Color code the output
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
if (hConsole != INVALID_HANDLE_VALUE) {
CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
GetConsoleScreenBufferInfo(hConsole, &consoleInfo);
WORD color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
switch (level) {
case LogLevel::ERROR:
case LogLevel::CRITICAL:
color = FOREGROUND_RED | FOREGROUND_INTENSITY;
break;
case LogLevel::WARNING:
color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
break;
case LogLevel::INFO:
color = FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY;
break;
case LogLevel::DEBUG:
case LogLevel::TRACE:
color = FOREGROUND_INTENSITY;
break;
}
SetConsoleTextAttribute(hConsole, color);
std::cout << logString;
SetConsoleTextAttribute(hConsole, consoleInfo.wAttributes);
} else {
std::cout << logString;
}
}
// Output to files
for (auto* file : m_fileStreams) {
if (file->is_open()) {
*file << logString;
file->flush();
}
}
}
// Convenience methods
void trace(const std::string& message, const char* file = nullptr, int line = 0) {
log(LogLevel::TRACE, message, file, line);
}
void debug(const std::string& message, const char* file = nullptr, int line = 0) {
log(LogLevel::DEBUG, message, file, line);
}
void info(const std::string& message, const char* file = nullptr, int line = 0) {
log(LogLevel::INFO, message, file, line);
}
void warning(const std::string& message, const char* file = nullptr, int line = 0) {
log(LogLevel::WARNING, message, file, line);
}
void error(const std::string& message, const char* file = nullptr, int line = 0) {
log(LogLevel::ERROR, message, file, line);
}
void critical(const std::string& message, const char* file = nullptr, int line = 0) {
log(LogLevel::CRITICAL, message, file, line);
}
};
Logger* Logger::s_instance = nullptr;
std::mutex Logger::s_mutex;
// 3. Logging Macros
#define LOG_TRACE(msg) Logger::getInstance().trace(msg, __FILE__, __LINE__)
#define LOG_DEBUG(msg) Logger::getInstance().debug(msg, __FILE__, __LINE__)
#define LOG_INFO(msg) Logger::getInstance().info(msg, __FILE__, __LINE__)
#define LOG_WARNING(msg) Logger::getInstance().warning(msg, __FILE__, __LINE__)
#define LOG_ERROR(msg) Logger::getInstance().error(msg, __FILE__, __LINE__)
#define LOG_CRITICAL(msg) Logger::getInstance().critical(msg, __FILE__, __LINE__)
// 4. Scoped Logger (RAII for timing)
class ScopedLogger {
private:
std::string m_name;
std::chrono::steady_clock::time_point m_start;
public:
explicit ScopedLogger(const std::string& name)
: m_name(name), m_start(std::chrono::steady_clock::now()) {
LOG_INFO("Entering: " + m_name);
}
~ScopedLogger() {
auto end = std::chrono::steady_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - m_start);
std::stringstream ss;
ss << "Exiting: " << m_name << " (took " << duration.count() << "ms)";
LOG_INFO(ss.str());
}
};
#define LOG_SCOPE(name) ScopedLogger _logger(name)
// 5. Conditional Logging
class ConditionalLogger {
public:
static void logIf(bool condition, const std::string& message, LogLevel level = LogLevel::INFO) {
if (condition) {
Logger::getInstance().log(level, message);
}
}
static void logOnce(int& flag, const std::string& message, LogLevel level = LogLevel::INFO) {
if (flag == 0) {
Logger::getInstance().log(level, message);
flag = 1;
}
}
};
// 6. Performance Logger
class PerformanceLogger {
private:
std::string m_operation;
std::chrono::steady_clock::time_point m_start;
public:
explicit PerformanceLogger(const std::string& operation)
: m_operation(operation), m_start(std::chrono::steady_clock::now()) {}
~PerformanceLogger() {
auto end = std::chrono::steady_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - m_start);
std::stringstream ss;
ss << "Performance: " << m_operation << " took " << duration.count() << " microseconds";
LOG_DEBUG(ss.str());
}
void checkpoint(const std::string& checkpointName) {
auto now = std::chrono::steady_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(now - m_start);
std::stringstream ss;
ss << "Checkpoint [" << checkpointName << "]: " << duration.count() << " microseconds";
LOG_DEBUG(ss.str());
}
};
#define LOG_PERFORMANCE(name) PerformanceLogger _perf(name)
// 7. Structured Logging
class StructuredLogger {
public:
struct LogEntry {
LogLevel level;
std::string message;
std::string category;
std::map<std::string, std::string> properties;
};
static void logStructured(const LogEntry& entry) {
std::stringstream ss;
ss << "[" << entry.category << "] " << entry.message;
if (!entry.properties.empty()) {
ss << " {";
bool first = true;
for (const auto& prop : entry.properties) {
if (!first) ss << ", ";
ss << prop.first << "=" << prop.second;
first = false;
}
ss << "}";
}
Logger::getInstance().log(entry.level, ss.str());
}
static void logEvent(const std::string& eventName, const std::map<std::string, std::string>& data) {
LogEntry entry;
entry.level = LogLevel::INFO;
entry.category = "EVENT";
entry.message = eventName;
entry.properties = data;
logStructured(entry);
}
};
// 8. Error Logging with Context
class ErrorLogger {
public:
static void logLastError(const std::string& context) {
DWORD error = GetLastError();
if (error == 0) return;
LPSTR messageBuffer = nullptr;
FormatMessageA(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
nullptr,
error,
0,
(LPSTR)&messageBuffer,
0,
nullptr
);
std::stringstream ss;
ss << context << " - Error " << error << ": " << messageBuffer;
Logger::getInstance().error(ss.str());
LocalFree(messageBuffer);
}
static void logException(const std::exception& e, const std::string& context = "") {
std::stringstream ss;
if (!context.empty()) {
ss << context << " - ";
}
ss << "Exception: " << e.what();
Logger::getInstance().error(ss.str());
}
};
// 9. Log Rotation (Simple)
class LogRotator {
private:
std::string m_baseFilename;
size_t m_maxFileSize;
int m_maxBackupCount;
public:
LogRotator(const std::string& filename, size_t maxSize = 1024 * 1024, int maxBackups = 5)
: m_baseFilename(filename), m_maxFileSize(maxSize), m_maxBackupCount(maxBackups) {}
bool shouldRotate() const {
std::ifstream file(m_baseFilename, std::ios::ate | std::ios::binary);
return file.is_open() && file.tellg() > m_maxFileSize;
}
void rotate() {
// Remove oldest backup if it exists
std::string oldestBackup = m_baseFilename + "." + std::to_string(m_maxBackupCount);
_unlink(oldestBackup.c_str());
// Rotate existing backups
for (int i = m_maxBackupCount - 1; i >= 1; i--) {
std::string oldName = m_baseFilename + "." + std::to_string(i);
std::string newName = m_baseFilename + "." + std::to_string(i + 1);
std::ifstream oldFile(oldName);
if (oldFile.good()) {
std::ofstream newFile(newName);
newFile << oldFile.rdbuf();
}
}
// Rename current log to .1
std::rename(m_baseFilename.c_str(), (m_baseFilename + ".1").c_str());
LOG_INFO("Log file rotated");
}
};
// Main demonstration
int main() {
std::cout << "=== Windows C++ Logging System Examples ===" << std::endl;
Logger& logger = Logger::getInstance();
// Configure logger
logger.setMinLevel(LogLevel::DEBUG);
logger.addLogFile("application.log");
logger.enableConsoleOutput(true);
logger.enableTimestamp(true);
logger.enableThreadId(false);
std::cout << "\n--- Basic Logging ---" << std::endl;
LOG_TRACE("This is a trace message");
LOG_DEBUG("This is a debug message");
LOG_INFO("This is an info message");
LOG_WARNING("This is a warning message");
LOG_ERROR("This is an error message");
LOG_CRITICAL("This is a critical message");
// 2. Scoped logging
std::cout << "\n--- Scoped Logging ---" << std::endl;
{
LOG_SCOPE("processData");
// Simulate work
Sleep(100);
}
// 3. Performance logging
std::cout << "\n--- Performance Logging ---" << std::endl;
{
LOG_PERFORMANCE("complexOperation");
Sleep(150);
}
// 4. Structured logging
std::cout << "\n--- Structured Logging ---" << std::endl;
std::map<std::string, std::string> eventData = {
{"userId", "12345"},
{"action", "login"},
{"ip", "192.168.1.1"}
};
StructuredLogger::logEvent("UserLogin", eventData);
// 5. Error logging
std::cout << "\n--- Error Logging ---" << std::endl;
try {
throw std::runtime_error("Simulated error");
} catch (const std::exception& e) {
ErrorLogger::logException(e, "During operation");
}
// 6. Conditional logging
std::cout << "\n--- Conditional Logging ---" << std::endl;
bool debugMode = true;
ConditionalLogger::logIf(debugMode, "Debug mode is enabled", LogLevel::DEBUG);
static int flag = 0;
ConditionalLogger::logOnce(flag, "This message will only appear once", LogLevel::INFO);
// Cleanup
logger.closeAllLogFiles();
std::cout << "\n=== All Logging Examples Completed ===" << std::endl;
return 0;
}