Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[98.81.24.230] |
|
Страницы: (2) [1] 2 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
В коде:
static size_t CreateVectorsFiles(vector<string>& vsFullname, vector<string>& vsFilename, const char* dir, const char* ext) { for (const fs::directory_entry& dir_entry : fs::recursive_directory_iterator(dir)) { if (fs::is_regular_file(dir_entry)) { if (fs::path(dir_entry).extension() == ext) { vsFullname.push_back(dir_entry.path().string()); vsFilename.push_back(fs::path(dir_entry).stem().string()); } } } return vsFilename.size(); } int main(int argc, char* argv[]) { setlocale(LC_ALL, "Russian"); for (int i = 0; i < argc; ++i) cout << argv[i] << endl; if (argc < 4) DisplayMessage("\nНе указаны параметры программы - директория для обработки, директория для результатов обработки и расширение файлов!\n", false); struct stat sb; if (stat(argv[1], &sb) != 0) DisplayMessage("\nДиректория для обработки не существует!\n", false); if (stat(argv[2], &sb) != 0) DisplayMessage("\nДиректория для записи результатов не существует!\n", false); vector<string> vsFullname, vsFilename; if (CreateVectorsFiles(vsFullname, vsFilename, argv[1], argv[3]) == 0) DisplayMessage("\nДиректория для обработки не содержит файлов с заданным расширением!\n", false); if (!fs::is_empty(argv[2])) DisplayMessage("\nВ директории для обработки есть файлы! Очистите директорию!\n", false); system("pause"); } "D:\TestProgramsDir" "D:\TestProgramsDir\Res" "*.txt" Прикреплённый файлTestProgramsDir.zip (3,73 Кбайт, скачиваний: 41) Прикреплённый файлcppProcFiles.zip (2,78 Кбайт, скачиваний: 40) |
Сообщ.
#2
,
|
|
|
Ну, не вполне очевидно, конечно, но всё ж на поверхности: ты под ext передаёшь argv[3], который задаёшь маской, тогда как std::filesystem::path::extension() возвращает именно что расширение. Неудивительно, что .txt не совпадает с *.txt
Добавлено P.S. А почему stat()? Почему не std::filesystem::is_directory()? |
Сообщ.
#3
,
|
|
|
Не знал об std::filesystem::is_directory(), теперь буду использовать. Заменил "*.txt" на "txt" - результат тот же
|
Сообщ.
#4
,
|
|
|
.txt
Добавлено Вообще, мы привыкли, что наборы файлов задаются маской. Я не знаю, что у тебя за задача, но предположу, что будет лучше фильтровать как раз маской, а не расширением. Даже если расширения достаточно, просто маской привычнее. К сожалению, std::filesystem::directory_iterator (и его рекурсивный аналог) не умеют маски, что с моей точки зрения является недочётом. Так что фильтровать нужно будет руками. Я бы предложил <regex>: std::string wildMask(ext); for (auto i = 0; i < wildMask.length(); ++i) if (wildMask[i] == '.') wildMask.replace(i++, 1, "\\."); else if (wildMask[i] == '*') wildMask.replace(i++, 1, ".*?"), ++i; else if (wildMask[i] == '?') wildMask[i] = '.'; std::regex mask(wildMask); /* ... */ if (std::regex_match(dir_entry.path().filename().string(), mask)) /* ...*/ Добавлено Но есть нюанс: учитывается регистр. Под POSIX пофигу, но в винде это важно. Сделать поиск регистронезависимым можно в конструкторе std::regex: std::regex mask(wildMask, std::regex_constants::icase); |
Сообщ.
#5
,
|
|
|
Спасибо большое, все отлично работает. Но все-таки хотелось бы узнать, как без маски выбирать все файлы в строке
if (fs::path(dir_entry).extension() == ext) |
Сообщ.
#6
,
|
|
|
Цитата tumanovalex @ Каким должен быть exp? Глянь тут, там в разделе Example есть пример, не требующий объяснений. |
Сообщ.
#7
,
|
|
|
Видимо, это для умных объяснений не надо. А я не разобрался.
|
Сообщ.
#8
,
|
|
|
Цитата tumanovalex @ А я не разобрался. Перевод описания: Цитата std::filesystem::path::extension Возвращает расширение компонента filename generic-формата пути *this. Если компонент filename() пути общего формата содержит точку (.) и не является одним из специальных элементов файловой системы dot или dot-dot, то расширением является подстрока, начинающаяся с крайней правой точки (включая точку) и до конца имени пути. Если первым символом в имени файла является точка, то эта точка игнорируется (имя файла типа ".profile" не рассматривается как расширение). Если имя пути содержит либо ., либо ..., либо если filename() не содержит символа '.', то возвращается пустой путь. Дополнительное поведение может быть определено реализациями для файловых систем, которые добавляют к расширениям дополнительные элементы (например, альтернативные потоки данных или имена наборов данных с разбиением на разделы). Переведено с помощью www.DeepL.com/Translator (бесплатная версия) Напиши, что именно тебе не понятно. |
Сообщ.
#9
,
|
|
|
Мне не понятно, каким должна быть переменная ext, чтобы вектора формировались из файлов с любыми расширениями. Если я указываю ".txt" или ".pdf", то вектора формируются из файлов с указанными расширениями.
Код Qraizer позволяет считывать как файлы с определенным расширением, так и все файлы в заданной директории. Причем отбора по признаку fs::is_regular_file(dir_entry) if (fs::path(dir_entry).extension() == ext) |
Сообщ.
#10
,
|
|
|
Цитата tumanovalex @ Каким должен быть exp? Пробовал "*", ".", " " - не получилось. Ответ простой - надо отлаживать программу. Методом тыка много не наработаешь. Ты строки сравниваешь тут ?: if (fs::path(dir_entry).extension() == ext) Перед сравнением выводи строки - да хоть printf-ом. |
Сообщ.
#11
,
|
|
|
Цитата ЫукпШ @ Перед сравнением выводи строки - да хоть printf-ом. Не понял, как это мне поможет. Я уже пробовал - extension() выводит расширение файла (".txt", ".pdf", ".cpp" и др.). Как я понял, код Qraizer сравнивает расширение с возможными комбинациями символов и если расширение есть в этой комбинации - то пропускает определенное расширение или же пропускает все расширения. Как я понял, фильтр с "== ext" сработает только для конкретного расширения и не срабатывает для всех файлов. Т.е. нельзя задать строку для exp, которая позволила бы пропускать файлы с любым расширением. Поэтому остается либо использовать этот фильтр только для конкретных расширений, либо в общем случае использовать код Qraizer. |
Сообщ.
#12
,
|
|
|
Цитата tumanovalex @ Мне не понятно, каким должна быть переменная ext, чтобы вектора формировались из файлов с любыми расширениями. У тебя изначально неверный подход к формулировке задачи ... Смотри аналогию: "Какой должна быть переменная int, чтобы она соответствовала любому значению?". Обычно так не бывает, и не может быть. Но хорошее решение есть - задавать переменную маской в виде регулярного выражения. И файлы искать не по "расширению" а по "маске". Выше Qraizer начал развивать эту мысль, но ты на это обратил недостаточно внимания, коль пытаешься решить своим изначально неправильным решением. |
Сообщ.
#13
,
|
|
|
Да я обратил внимание. Код проверил, отлично работает для конкретных и всех расширений. Действительно, что-то у меня в понятиях сбилось - сравниваю конкретной расширение с шаблоном и при этом хочу, чтобы фильтровались все расширения. Так что прошу прощения за навязанную глупую дискуссию.
|
Сообщ.
#14
,
|
|
|
Цитата tumanovalex @ при этом хочу, чтобы фильтровались все расширения Ну вот пример регулярки, которая одна фильтрует (ловит) файлы с пятью расширениями. Можно регулярку усложнить. Можно наоборот писать простые регулярки, но чекать в цикле набор регулярок. Основная идея - на привязываться к расширению файла, как к таковому, а использовать маску или маски файлов. |
Сообщ.
#15
,
|
|
|
Спасибо, буду разбираться.
|