Skip to content

Instantly share code, notes, and snippets.

@decagondev
Created September 5, 2025 21:39
Show Gist options
  • Save decagondev/813b2a2a593d920a962918723a6dbc84 to your computer and use it in GitHub Desktop.
Save decagondev/813b2a2a593d920a962918723a6dbc84 to your computer and use it in GitHub Desktop.

Exercise 2: File Search Utility

Overview

Welcome to Exercise 2! In this project, you'll build a File Search Utility for Windows using C++. This console application allows users to search for files in a specified directory based on various criteria. It's a great opportunity to practice working with the Windows API, handling command-line arguments, and applying C++ best practices like proper string handling and resource management.

The goal is to create a single-file C++ program that is simple, efficient, and robust. You'll implement functionality to filter files by name patterns, size ranges, modification dates, and file attributes, all while keeping the code idiomatic and maintainable.

Objectives

Your task is to create a command-line utility that:

  • Searches files in a given directory (non-recursively).
  • Filters files based on:
    • File name patterns (supporting wildcards like * and ?).
    • File size ranges (minimum and maximum sizes in bytes).
    • Modification date ranges (start and end dates).
    • File attributes (e.g., hidden, readonly).
  • Outputs the full paths of matching files to the console.
  • Handles Unicode file paths for broader compatibility.
  • Uses a single .cpp file with no external dependencies beyond standard C++ and Windows libraries.

Getting Started

Prerequisites

  • A Windows environment (e.g., Windows 10 or 11).
  • A C++ compiler, such as:
    • Visual Studio (Community Edition is fine) with C++ support.
    • MinGW-w64 (ensure it includes the Windows API headers).
  • Basic knowledge of:
    • C++ (strings, maps, command-line argument handling).
    • Windows API for file operations (e.g., FindFirstFile).
    • Working with FILETIME and SYSTEMTIME for dates.

Setup

  1. Create a new C++ project or a single .cpp file (e.g., FileSearch.cpp).
  2. Ensure you link against kernel32.lib (included by default in most Windows C++ environments).
  3. Write your code to handle command-line arguments and interact with the Windows file system.

Command-Line Interface

Your program should accept exactly 7 command-line arguments in this order:

  1. Directory path (e.g., C:\Temp).
  2. File name pattern (e.g., *.txt or empty for all files).
  3. Minimum file size in bytes (e.g., 1024 or -1 for no minimum).
  4. Maximum file size in bytes (e.g., 1048576 or -1 for no maximum).
  5. Start date for modification time (e.g., 2023-01-01 or empty for no start limit).
  6. End date for modification time (e.g., 2023-12-31 or empty for no end limit).
  7. Comma-separated file attributes (e.g., hidden,system or empty for no filter).

Example Command:

FileSearch.exe C:\Temp *.txt 1024 -1 2023-01-01 2023-12-31 hidden,system

Expected Output:

  • Full paths of matching files, one per line, printed to the console (e.g., C:\Temp\example.txt).
  • If no files match or the directory is invalid, handle gracefully (e.g., no output or an error message).

Tips for Success

  • Use Windows API: Leverage functions like FindFirstFileW and FindNextFileW for file enumeration. Use wide-character versions (W suffix) for Unicode support.
  • Handle Dates: Convert date strings to FILETIME for comparison with file modification times. Consider edge cases like empty date inputs.
  • File Attributes: Use DWORD flags (e.g., FILE_ATTRIBUTE_HIDDEN) and bitwise operations to check multiple attributes.
  • Error Handling: Check for invalid directories, handles, and input formats. Provide clear usage instructions if arguments are incorrect.
  • Keep It Simple: Focus on non-recursive search to avoid complexity. Use standard library containers like std::map or std::vector for clean code.
  • Unicode Support: Use std::wstring and wide-character APIs to handle international file names.
  • Best Practices: Avoid raw pointers, use RAII for resource cleanup (e.g., closing file handles), and handle exceptions where appropriate.

Learning Goals

By completing this exercise, you'll:

  • Gain experience with Windows file system APIs.
  • Practice parsing and validating command-line arguments.
  • Learn to handle file attributes and timestamps in C++.
  • Apply modern C++ techniques (e.g., standard library containers, type safety).
  • Understand basic error handling and user feedback in console applications.

Testing Your Program

  • Test with different directories, including ones with spaces or Unicode characters.
  • Try various patterns (e.g., *.txt, file?.doc).
  • Test size ranges (e.g., files between 1 KB and 1 MB).
  • Use date ranges to filter files modified within a specific period.
  • Test attribute combinations (e.g., hidden and readonly files).
  • Verify behavior with invalid inputs (e.g., non-existent directories, malformed dates).

Resources

  • Windows API Documentation: Look up FindFirstFileW, FILETIME, and SystemTimeToFileTime on MSDN.
  • C++ Reference: Use cppreference.com for std::wstring, std::stringstream, and other standard library features.
  • Compiler Setup: If using Visual Studio, create a "Console Application" project. For MinGW, compile with g++ FileSearch.cpp -o FileSearch.exe.

Get started and have fun building your file search utility! Focus on clean, maintainable code, and test thoroughly to ensure robustness.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment