Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * find.exe <directory> -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 <iostream> // Для cin, cout, endl
- #include <string> // для string
- #include <vector> // для vector
- #include <windows.h> // для поиска файлов - WIN32_FIND_DATA, HANDLE, FindFirstFile, ...
- #include <algorithm> // Для сортировки sort()
- using namespace std;
- // Структура данных о файле.
- // Содержит название, аттрибуты, и прочее
- WIN32_FIND_DATA fileData;
- HANDLE handle; // Поисковой дискриптор. Нужен для функции FindFirstFile
- // Функция нужна для поиска папок в заданной папке
- // Например На диске C:\ есть папки dir1 и dir2
- // Тогда вызвав findSubdirectory("C:\") получим вектор с "dir1" и "dir2"
- vector<string> findSubdirectory(string &dir) {
- vector<string> 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<string> findFiles(string &filePatch) {
- vector<string> 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<string> из найденных файлов, а потом отсортировать их
- // А если нам не нужно сортировать - то мы можем сразу выводить найденные файлы
- //
- // dir - директория, например C:\ или C:\Users\Alex
- // fileName - название файла, myFile.cpp или *file.*
- // result - результат. Сюда будем записывать найденные файлы.
- void find(vector<string> &result, string &dir, string &fileName, bool needSave) {
- // 1. Ищем файлы в текущей директории
- vector<string> 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<string> 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 <directory> -name <fileName> [-abc/-cab]" << endl;
- return 0;
- }
- vector<string> 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;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement