/** * find.exe -name "file.*" * -abc сортирует по возрастанию, -cba по убывания * Пример find.exe C:\test\ -name "*.txt" -abc * Что выведет: * C:\test\folder2\doc.txt * C:\test\folder2\doc1.txt * C:\test\folder3\folder2\doc1.txt */ #include // Для cin, cout, endl #include // для string #include // для vector #include // для поиска файлов - WIN32_FIND_DATA, HANDLE, FindFirstFile, ... #include // Для сортировки sort() using namespace std; // Структура данных о файле. // Содержит название, аттрибуты, и прочее WIN32_FIND_DATA fileData; HANDLE handle; // Поисковой дискриптор. Нужен для функции FindFirstFile // Функция нужна для поиска папок в заданной папке // Например На диске C:\ есть папки dir1 и dir2 // Тогда вызвав findSubdirectory("C:\") получим вектор с "dir1" и "dir2" vector findSubdirectory(string &dir) { vector subdirectories; // Массив с названием папок // Создаем поисковой дискриптор handle = FindFirstFile(dir.c_str(), &fileData); // INVALID_HANDLE_VALUE возникает когда не найден путь/директория if (handle != INVALID_HANDLE_VALUE) { // Выполняем цикл, пока существуют файлы do { // Если найденная сущность является папкой, добавляем название в массив папок if ((fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { subdirectories.push_back(fileData.cFileName); } } while (FindNextFile(handle, &fileData) != 0); } FindClose(handle); return subdirectories; } // Функция нужна для поиска файлов. // На вход подается строка, директория + название файла. Поддерживает маску. // Например C:\test.* или C:\* или C:\test\dir\file.doc // Возвращаемое значение - вектор с названиями файлов (без директории) vector findFiles(string &filePatch) { vector result; handle = FindFirstFile(filePatch.c_str(), &fileData); if (handle != INVALID_HANDLE_VALUE) { do { //если найденный файл не является папкой добавляем его в вектор if ((fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) { result.push_back(fileData.cFileName); } } while (FindNextFile(handle, &fileData) != 0); FindClose(handle); } return result; } // Поиск файла // 1. Ищем файл в текущей директории // 2. Ищем все субдиректории // 3. Для каждой субдиректории выполняем эту же функцию // // Если нам нужно сортировать результат, то сначала мы должны создать // vector из найденных файлов, а потом отсортировать их // А если нам не нужно сортировать - то мы можем сразу выводить найденные файлы // // dir - директория, например C:\ или C:\Users\Alex // fileName - название файла, myFile.cpp или *file.* // result - результат. Сюда будем записывать найденные файлы. void find(vector &result, string &dir, string &fileName, bool needSave) { // 1. Ищем файлы в текущей директории vector files = findFiles(dir + fileName); // Если не нужно сохранять, то выводим найденные файлы if (!needSave) { for (auto findFileName : files) { cout << dir << findFileName << endl; } // Если нужно сохранять, то добавляем найденные файлы в result } else { for (auto fileName : files) { result.push_back(dir + fileName); } } // 2. Ищем все папки в текущей директории vector dirs = findSubdirectory(dir + "*"); // 3. Для всех найденных папок выполням эту же функцию // Указатели на текущую директорию "." и на директорию выше ".." не учитываем for (auto find_dir : dirs) { if (find_dir != "." && find_dir != "..") { // cout << "Выплняем поиск в папке " << (dir + find_dir) << endl; find(result, dir + find_dir + "\\", fileName, needSave); } } } // argc - кол-во аргументов, переданное программе // argv - сами аргументы int main(int argc, char* argv[]) { setlocale(LC_ALL, "Russian"); string directory; string fileName; int sort = 0; // "1" - abc, "-1" - cba, "0" - нет сортировки // Для всех аргументов for (int i = 0; i < argc; ++i) { string arg = argv[i]; // Первым аргументом задаётся директория if (i == 1) directory = arg; else if (arg == "-abc") sort = 1; else if (arg == "-cba") sort = -1; else if (arg == "-name") { fileName = argv[i + 1]; i++; } } // Если не задана директория или название файла - выходим из программы if (directory.size() == 0 || fileName.size() == 0) { cout << "Используйте find.exe -name [-abc/-cab]" << endl; return 0; } vector result; // Вызываем функцию для рекурсивного поиска файлов find(result, directory, fileName, (sort != 0)); if (sort != 0) { // Сортируем от A до Z std::sort(result.begin(), result.end()); // Если нужно соритровать в обратном порядке, реверсим массив if (sort == -1) std::reverse(result.begin(), result.end()); for (auto fileName : result) { cout << fileName << endl; } } return 0; }