@chrish - Да, но у этого есть классическое "Я не могу выполнить 'ls'"! Это именно то, что я чувствую на первом курсе информатики. ; D <3 x
Джеймс Бедфорд
1
C и C ++ - это не один и тот же язык. Таким образом, процедура для выполнения этой задачи будет отличаться на обоих языках. Пожалуйста, выберите один и пометить соответствующим образом.
MD XF
2
И ни один из этих языков (кроме C ++ начиная с C ++ 17) даже не имеет понятия каталога - так что любой ответ, вероятно, будет зависеть от вашей ОС или от любых библиотек абстракции, которые вы можете использовать.
Тоби Спейт
Ответы:
810
В небольших и простых задачах я не использую boost, я использую dirent.h, который также доступен для windows:
DIR *dir;struct dirent *ent;if((dir = opendir ("c:\\src\\"))!= NULL){/* print all the files and directories within directory */while((ent = readdir (dir))!= NULL){
printf ("%s\n", ent->d_name);}
closedir (dir);}else{/* could not open directory */
perror ("");return EXIT_FAILURE;}
Это всего лишь небольшой заголовочный файл, который выполняет большинство простых задач без использования большого подхода на основе шаблонов, такого как boost (без обид, мне нравится boost!).
Автор слоя совместимости окон - Тони Ронкко. В Unix это стандартный заголовок.
ОБНОВЛЕНИЕ 2017 :
В C ++ 17 есть теперь официальный способ список файлов в файловой системе: std::filesystem. Ниже приведен отличный ответ от Shreevardhan с этим исходным кодом:
@ArtOfWarfare: tinydir даже не был создан, когда на этот вопрос был дан ответ. Также это обертка вокруг dirent (POSIX) и FindFirstFile (Windows), в то время как dirent.h просто оборачивает dirent для окон. Я думаю, что это личный вкус, но dirent.h чувствует себя больше как стандарт
Питер Паркер
7
@JoshC: потому что * ent - это просто возвращаемый указатель внутреннего представления. закрыв каталог, вы также удалите * ent. Поскольку * ent только для чтения, я думаю, что это нормальный дизайн.
Питер Паркер
42
люди становятся настоящими !! это вопрос 2009 года, и он даже не упомянул VS. Так что не критикуйте, что ваша полная проприетарная (хотя и довольно приятная) IDE не поддерживает многовековые стандарты ОС. Также в моем ответе говорилось, что оно «доступно» для windows, а не «включено» в любую IDE с этого момента и на все времена ... Я совершенно уверен, что вы можете скачать dirent и поместить его в некоторые include dir и вуаля, где это так.
Питер Паркер
6
Ответ вводит в заблуждение. Он должен начинаться с: « ... я использую dirent.h , для которого также существует слой совместимости с открытым исходным кодом Windows ».
rustyx
10
С C ++ 14 есть std::experimental::filesystem, с C ++ 17 есть std::filesystem. Смотрите ответ Shreevardhan ниже. Так что нет необходимости в сторонних библиотеках.
AFAIK также могут быть использованы в C ++ 14, но он все еще экспериментальный: namespace fs = std::experimental::filesystem;. Кажется, все работает хорошо, хотя.
PeterK
7
Это должно быть предпочтительным ответом для текущего использования (начиная с C ++ 17)
зеленый диод
4
Heed при переходе std::filesystem::pathк std::cout, кавычки включены в вывод. Чтобы избежать этого, добавьте .string()к пути, чтобы сделать явное вместо неявного преобразования (здесь std::cout << p.string() << std::endl;). Пример: coliru.stacked-crooked.com/view?id=a55ea60bbd36a8a3
Рой Дантон,
2
Как насчет символов без ASCII в именах файлов? Не std::wstringдолжен использоваться или какой тип у итератора?
Андеро
2
Я не уверен, что я один в этом, но без ссылки -lstdc++fsя бы получил SIGSEGV (Address boundary error). Я не мог найти в документации нигде, что это требуется, и компоновщик также не дал никакой подсказки. Это сработало для обоих g++ 8.3.0и clang 8.0.0-3. У кого-нибудь есть понимание того, где такие вещи указаны в документации / спецификации?
Сулог
229
К сожалению, стандарт C ++ не определяет стандартный способ работы с файлами и папками таким образом.
Поскольку кроссплатформенного способа не существует, лучшим кроссплатформенным способом является использование библиотеки, такой как модуль надстройки файловой системы .
Кроссплатформенный метод повышения:
Следующая функция, учитывая путь к каталогу и имя файла, рекурсивно ищет в каталоге и его подкаталогах имя файла, возвращая bool, а в случае успеха - путь к найденному файлу.
bool find_file(const path & dir_path,// in this directory,const std::string& file_name,// search for this name,
path & path_found)// placing path here if found{if(!exists(dir_path))returnfalse;
directory_iterator end_itr;// default construction yields past-the-endfor(directory_iterator itr(dir_path); itr != end_itr;++itr){if(is_directory(itr->status())){if(find_file(itr->path(), file_name, path_found))returntrue;}elseif(itr->leaf()== file_name)// see below{
path_found = itr->path();returntrue;}}returnfalse;}
С C ++ 14 есть std::experimental::filesystem, с C ++ 17 есть std::filesystem, у которых есть подобная функциональность как boost (библиотеки получены из boost). Смотрите ответ Shreevardhan ниже.
Это решение, если для конкретной платформы. Вот почему вам нужны сторонние библиотеки.
kraxor
9
@kraxor Да, он работает только в Windows, но OP никогда не просит кроссплатформенного решения. Кстати, я всегда предпочитаю выбирать что-то без использования 3-х библиотек (если это возможно).
herohuyongtao
7
@herohuyongtao OP никогда не указывал платформу, и предоставление решения, в основном зависящего от платформы, для общего вопроса может ввести в заблуждение. (Что, если существует однострочное решение, которое работает только на PlayStation 3? Это хороший ответ здесь?) Я вижу, вы отредактировали свой ответ, заявив, что он работает только в Windows, я думаю, что это нормально.
kraxor
1
@herohuyongtao ОП упомянул, что не может разобрать ls, то есть он, вероятно, работает на Unix ... в любом случае, хороший ответ для Windows.
Томас
2
В итоге я использовал a, std::vector<std::wstring>а затем fileName.c_str()вместо вектора строк, который не будет компилироваться.
PerryC
51
Для решения C only, пожалуйста, проверьте это. Требуется только дополнительный заголовок:
Очень хорошее предложение. Я еще не тестировал его на компьютере с Windows, но он отлично работает на OS X.
ArtOfWarfare
Библиотека не поддерживает std :: string, поэтому вы не можете передать file.c_str () в tinydir_open. В этом случае выдает ошибку C2664 во время компиляции на msvc 2015.
Степан Яковенко
33
Я рекомендую использовать globс этой многоразовой оберткой. Он генерирует vector<string>соответствующие пути к файлам, которые соответствуют шаблону glob:
Я хотел бы использовать glob.h, как вы рекомендовали. Но все же я не могу включить файл .h: он говорит No such file or directory. Можете ли вы сказать мне, как решить эту проблему, пожалуйста?
Tofuw
Обратите внимание, что эта процедура проходит только на один уровень (без рекурсии). Он также не делает быструю проверку , чтобы определить , является ли это файл или каталог, который вы можете легко сделать путем переключения GLOB_TILDEс , GLOB_TILDE | GLOB_MARKа затем проверка путей , заканчивающихся косой чертой. Вы должны будете внести любые изменения в него, если вам это нужно.
Volomike
Является ли это кроссплатформенным совместимым?
Нихил Августин
К сожалению, вы не можете найти одинаково скрытые файлы через glob.
LmTinyToon
23
Вот очень простой код C++11использования boost::filesystemбиблиотеки для получения имен файлов в каталоге (исключая имена папок):
#include<string>#include<iostream>#include<boost/filesystem.hpp>usingnamespace std;usingnamespace boost::filesystem;int main(){
path p("D:/AnyFolder");for(auto i = directory_iterator(p); i != directory_iterator(); i++){if(!is_directory(i->path()))//we eliminate directories{
cout << i->path().filename().string()<< endl;}elsecontinue;}}
struct dirent {ino_t d_ino;/* inode number */off_t d_off;/* offset to the next dirent */unsignedshort d_reclen;/* length of this record */unsignedchar d_type;/* type of file */char d_name[256];/* filename */};
Хотя эта ссылка может ответить на вопрос, лучше включить сюда основные части ответа и предоставить ссылку для справки. Ответы, содержащие только ссылки, могут стать недействительными, если связанная страница изменится. - Из обзора
ice1000
@ ice1000 Серьезно? Это Q & A от 2009
Тим
8
Проверьте этот класс, который использует Win32 API. Просто создайте экземпляр, предоставив список, foldernameиз которого вы хотите получить листинг, затем вызовите getNextFileметод для получения следующего filenameиз каталога. Я думаю, что это необходимо windows.hи stdio.h.
classFileGetter{
WIN32_FIND_DATAA found;
HANDLE hfind;char folderstar[255];int chk;public:FileGetter(char* folder){
sprintf(folderstar,"%s\\*.*",folder);
hfind =FindFirstFileA(folderstar,&found);//skip .FindNextFileA(hfind,&found);}int getNextFile(char* fname){//skips .. when called for the first time
chk=FindNextFileA(hfind,&found);if(chk)
strcpy(fname, found.cFileName);return chk;}};
Кроме того, иногда хорошо идти прямо к источнику (каламбур). Вы можете многому научиться, взглянув на внутренности некоторых наиболее распространенных команд в Linux. Я установил простое зеркало coreutils GNU на github (для чтения).
-1. string2wchar_tвозвращает адрес локальной переменной. Кроме того, вам, вероятно, следует использовать методы преобразования, доступные в WinAPI, вместо того, чтобы писать свои собственные.
Даниэль Камил Козар
3
Эта реализация реализует вашу цель, динамически заполняя массив строк содержимым указанного каталога.
int exploreDirectory(constchar*dirpath,char***list,int*numItems){struct dirent **direntList;int i;
errno =0;if((*numItems = scandir(dirpath,&direntList, NULL, alphasort))==-1)return errno;if(!((*list)= malloc(sizeof(char*)*(*numItems)))){
fprintf(stderr,"Error in list allocation for file list: dirpath=%s.\n", dirpath);exit(EXIT_FAILURE);}for(i =0; i <*numItems; i++){(*list)[i]= stringDuplication(direntList[i]->d_name);}for(i =0; i <*numItems; i++){
free(direntList[i]);}
free(direntList);return0;}
Как бы я это назвал? Я получаю segfaults, когда пытаюсь запустить эту функцию в первом ifблоке. Я звоню сchar **list; int numItems; exploreDirectory("/folder",list, numItems);
Hal T
2
Это работает для меня. Извините, если не могу вспомнить источник. Это, вероятно, со страницы руководства.
вы можете получить все прямые файлы в вашем корневом каталоге, используя std :: эксперимент :: filesystem :: directory_iterator (). Затем прочитайте имя этих файлов.
Вставьте приведенный ниже void filefinder()метод в свой код и вызовите его из своей mainфункции или отредактируйте функцию так, как вы хотите ее использовать.
#include<stdio.h>#include<string.h>#include"dirent.h"string path ="C:/folder";//Put a valid path here for foldervoid filefinder(){
DIR *directory = opendir(path.c_str());struct dirent *direntStruct;if(directory != NULL){while(direntStruct = readdir(directory)){
printf("File Name: %s\n", direntStruct->d_name);//If you are using <stdio.h>//std::cout << direntStruct->d_name << std::endl; //If you are using <iostream>}}
closedir(directory);}
РЕДАКТИРОВАТЬ: Этот ответ следует считать взломать, но он действительно работает (хотя и в зависимости от платформы), если у вас нет доступа к более элегантным решениям.
Мне не разрешено выполнять команду 'ls' и анализировать результаты из моей программы. Я знал, что будет кто-то, кто отправит что-то вроде этого ...
yyny
1
Поскольку файлы и подкаталоги каталога обычно хранятся в древовидной структуре, интуитивно понятным способом является использование алгоритма DFS для рекурсивного обхода каждого из них. Вот пример в операционной системе Windows с использованием основных файловых функций в io.h. Вы можете заменить эти функции на другой платформе. Что я хочу выразить, так это то, что основная идея DFS прекрасно соответствует этой проблеме.
#include<io.h>#include<iostream.h>#include<string>usingnamespace std;voidTraverseFilesUsingDFS(conststring& folder_path){_finddata_t file_info;string any_file_pattern = folder_path +"\\*";intptr_t handle = _findfirst(any_file_pattern.c_str(),&file_info);//If folder_path exsist, using any_file_pattern will find at least two files "." and "..", //of which "." means current dir and ".." means parent dirif(handle ==-1){
cerr <<"folder path not exist: "<< folder_path << endl;exit(-1);}//iteratively check each file or sub_directory in current folderdo{string file_name=file_info.name;//from char array to string//check whtether it is a sub direcotry or a fileif(file_info.attrib & _A_SUBDIR){if(file_name !="."&& file_name !=".."){string sub_folder_path = folder_path +"\\"+ file_name;TraverseFilesUsingDFS(sub_folder_path);
cout <<"a sub_folder path: "<< sub_folder_path << endl;}}else
cout <<"file name: "<< file_name << endl;}while(_findnext(handle,&file_info)==0);//
_findclose(handle);}
Я попытался следовать примеру, приведенному в обоих ответах, и, возможно, стоит отметить, что он выглядит так, как будто std::filesystem::directory_entryон был изменен, чтобы не иметь перегрузки <<оператора. Вместо этого std::cout << p << std::endl;я должен был использовать следующее, чтобы иметь возможность скомпилировать и заставить его работать:
Если вы знаете, что вы будете использовать только многобайтовые, вы можете использовать WIN32_FIND_DATAA, FindFirstFileAи FindNextFileA. Тогда не будет необходимости преобразовывать результат в многобайтовый или ввод в Unicode.
Киран Тилак
0
Просто то, чем я хочу поделиться и поблагодарить вас за материал для чтения. Поиграйте с функцией, чтобы немного ее понять. Вам может понравиться это. e обозначает расширение, p обозначает путь, а s обозначает разделитель пути.
Если путь пропущен без конечного разделителя, разделитель будет добавлен к пути. Для расширения, если введена пустая строка, функция вернет любой файл, который не имеет расширения в своем имени. Если была введена одна звезда, будут возвращены все файлы в каталоге. Если длина e больше 0, но не является единственной *, то точка e будет добавлена к e, если e не содержала точку в нулевой позиции.
Для возвращаемого значения. Если возвращается карта нулевой длины, то ничего не найдено, но каталог открыт. Если индекс 999 доступен из возвращаемого значения, но размер карты равен только 1, это означало, что возникла проблема с открытием пути к каталогу.
Обратите внимание, что для эффективности эту функцию можно разделить на 3 меньшие функции. Кроме того, вы можете создать функцию вызывающей стороны, которая будет определять, какую функцию она будет вызывать, основываясь на вводе. Почему это более эффективно? Сказано, что если вы собираетесь захватить все, что является файлом, то при использовании этого метода подфункция, созданная для захвата всех файлов, будет просто захватывать все файлы и не должна оценивать какие-либо другие ненужные условия при каждом обнаружении файла.
Это также относится к случаям, когда вы получаете файлы, которые не имеют расширения. Специальная встроенная функция для этой цели будет оценивать погоду только в том случае, если найденный объект является файлом, а затем, будет ли в имени файла точка.
Экономия может быть невелика, если вы только читаете каталоги с небольшим количеством файлов. Но если вы читаете большое количество каталогов или если каталог содержит пару сотен тысяч файлов, это может быть огромной экономией.
#include<stdio.h>#include<sys/stat.h>#include<iostream>#include<dirent.h>#include<map>
std::map<int, std::string> getFile(std::string p, std::string e ="",unsignedchar s ='/'){if( p.size()>0){if(p.back()!= s) p += s;}if( e.size()>0){if( e.at(0)!='.'&&!(e.size()==1&& e.at(0)=='*')) e ="."+ e;}
DIR *dir;struct dirent *ent;struct stat sb;
std::map<int, std::string> r ={{999,"FAILED"}};
std::string temp;int f =0;bool fd;if((dir = opendir(p.c_str()))!= NULL ){
r.erase (999);while((ent = readdir (dir))!= NULL){
temp = ent->d_name;
fd = temp.find(".")!= std::string::npos?true:false;
temp = p + temp;if(stat(temp.c_str(),&sb)==0&& S_ISREG(sb.st_mode)){if( e.size()==1&& e.at(0)=='*'){
r[f]= temp;
f++;}else{if(e.size()==0){if( fd ==false){
r[f]= temp;
f++;}continue;}if(e.size()> temp.size())continue;if( temp.substr(temp.size()- e.size())== e ){
r[f]= temp;
f++;}}}}
closedir(dir);return r;}else{return r;}}void printMap(auto&m){for(constauto&p : m){
std::cout <<"m["<< p.first <<"] = "<< p.second << std::endl;}}int main(){
std::map<int, std::string> k = getFile("./","");
printMap(k);return0;}
stat()
ошибку «нет такого файла или каталога», когда имя файла возвращаетсяreaddir()
.Ответы:
В небольших и простых задачах я не использую boost, я использую dirent.h, который также доступен для windows:
Это всего лишь небольшой заголовочный файл, который выполняет большинство простых задач без использования большого подхода на основе шаблонов, такого как boost (без обид, мне нравится boost!).
Автор слоя совместимости окон - Тони Ронкко. В Unix это стандартный заголовок.
ОБНОВЛЕНИЕ 2017 :
В C ++ 17 есть теперь официальный способ список файлов в файловой системе:
std::filesystem
. Ниже приведен отличный ответ от Shreevardhan с этим исходным кодом:источник
std::experimental::filesystem
, с C ++ 17 естьstd::filesystem
. Смотрите ответ Shreevardhan ниже. Так что нет необходимости в сторонних библиотеках.C ++ 17 теперь имеет
std::filesystem::directory_iterator
, который можно использовать какТакже
std::filesystem::recursive_directory_iterator
можно перебирать подкаталоги.источник
namespace fs = std::experimental::filesystem;
. Кажется, все работает хорошо, хотя.std::filesystem::path
кstd::cout
, кавычки включены в вывод. Чтобы избежать этого, добавьте.string()
к пути, чтобы сделать явное вместо неявного преобразования (здесьstd::cout << p.string() << std::endl;
). Пример: coliru.stacked-crooked.com/view?id=a55ea60bbd36a8a3std::wstring
должен использоваться или какой тип у итератора?-lstdc++fs
я бы получилSIGSEGV (Address boundary error)
. Я не мог найти в документации нигде, что это требуется, и компоновщик также не дал никакой подсказки. Это сработало для обоихg++ 8.3.0
иclang 8.0.0-3
. У кого-нибудь есть понимание того, где такие вещи указаны в документации / спецификации?К сожалению, стандарт C ++ не определяет стандартный способ работы с файлами и папками таким образом.
Поскольку кроссплатформенного способа не существует, лучшим кроссплатформенным способом является использование библиотеки, такой как модуль надстройки файловой системы .
Кроссплатформенный метод повышения:
Источник со страницы поддержки, упомянутой выше.
Для систем на основе Unix / Linux:
Вы можете использовать opendir / readdir / closedir .
Исходный код с вышеупомянутых man-страниц.
Для систем на базе Windows:
Вы можете использовать функции Win32 API FindFirstFile / FindNextFile / FindClose .
Исходный код с указанных выше страниц MSDN.
источник
FindFirstFile(TEXT("D:\\IMAGE\\MYDIRECTORY\\*"), &findFileData);
std::experimental::filesystem
, с C ++ 17 естьstd::filesystem
, у которых есть подобная функциональность как boost (библиотеки получены из boost). Смотрите ответ Shreevardhan ниже.Одной функции достаточно, вам не нужно использовать какую-либо стороннюю библиотеку (для Windows).
PS: как упомянул @Sebastian, вы можете перейти
*.*
на*.ext
, чтобы получить только EXT-файлы (т.е. определенного типа) в этом каталоге.источник
std::vector<std::wstring>
а затемfileName.c_str()
вместо вектора строк, который не будет компилироваться.Для решения C only, пожалуйста, проверьте это. Требуется только дополнительный заголовок:
https://github.com/cxong/tinydir
Некоторые преимущества перед другими вариантами:
readdir_r
там, где доступно, что означает (как правило) потокобезопасностьUNICODE
макросыисточник
Я рекомендую использовать
glob
с этой многоразовой оберткой. Он генерируетvector<string>
соответствующие пути к файлам, которые соответствуют шаблону glob:Который затем может быть вызван с нормальным системным шаблоном подстановки, таким как:
источник
No such file or directory
. Можете ли вы сказать мне, как решить эту проблему, пожалуйста?GLOB_TILDE
с ,GLOB_TILDE | GLOB_MARK
а затем проверка путей , заканчивающихся косой чертой. Вы должны будете внести любые изменения в него, если вам это нужно.glob
.Вот очень простой код
C++11
использованияboost::filesystem
библиотеки для получения имен файлов в каталоге (исключая имена папок):Вывод как:
источник
boost::filesystem
библиотеку boost.org/doc/libs/1_58_0/libs/filesystem/doc/index.htmПочему бы не использовать
glob()
?источник
Я думаю, ниже фрагмент может быть использован для перечисления всех файлов.
Ниже приведена структура struct dirent
источник
Попробуйте повысить для метода X-платформы
http://www.boost.org/doc/libs/1_38_0/libs/filesystem/doc/index.htm
или просто используйте файлы, специфичные для вашей ОС.
источник
Проверьте этот класс, который использует Win32 API. Просто создайте экземпляр, предоставив список,
foldername
из которого вы хотите получить листинг, затем вызовитеgetNextFile
метод для получения следующегоfilename
из каталога. Я думаю, что это необходимоwindows.h
иstdio.h
.источник
GNU Manual FTW
http://www.gnu.org/software/libc/manual/html_node/Simple-Directory-Lister.html#Simple-Directory-Lister
Кроме того, иногда хорошо идти прямо к источнику (каламбур). Вы можете многому научиться, взглянув на внутренности некоторых наиболее распространенных команд в Linux. Я установил простое зеркало coreutils GNU на github (для чтения).
https://github.com/homer6/gnu_coreutils/blob/master/src/ls.c
Возможно, это не относится к Windows, но с помощью этих методов может быть несколько случаев использования вариантов Unix.
Надеюсь, это поможет...
источник
Shreevardhan ответ отлично работает. Но если вы хотите использовать его в C ++ 14, просто внесите изменения
namespace fs = experimental::filesystem;
т.е.
источник
источник
Я надеюсь, что этот код поможет вам.
источник
string2wchar_t
возвращает адрес локальной переменной. Кроме того, вам, вероятно, следует использовать методы преобразования, доступные в WinAPI, вместо того, чтобы писать свои собственные.Эта реализация реализует вашу цель, динамически заполняя массив строк содержимым указанного каталога.
источник
if
блоке. Я звоню сchar **list; int numItems; exploreDirectory("/folder",list, numItems);
Это работает для меня. Извините, если не могу вспомнить источник. Это, вероятно, со страницы руководства.
источник
вы можете получить все прямые файлы в вашем корневом каталоге, используя std :: эксперимент :: filesystem :: directory_iterator (). Затем прочитайте имя этих файлов.
источник
Этот ответ должен работать для пользователей Windows, которые столкнулись с трудностями при работе с Visual Studio с любыми другими ответами.
Загрузите файл dirent.h со страницы github. Но лучше всего использовать файл Raw dirent.h и следовать моим инструкциям ниже (именно так я и получил).
Страница Github для dirent.h для Windows: Страница Github для dirent.h
Файл Raw Dirent : Файл Raw dirent.h
Перейдите в свой проект и добавьте новый элемент ( Ctrl+ Shift+ A). Добавьте файл заголовка (.h) и назовите его dirent.h.
Вставьте код файла Raw dirent.h в свой заголовок.
Включите "dirent.h" в свой код.
Вставьте приведенный ниже
void filefinder()
метод в свой код и вызовите его из своейmain
функции или отредактируйте функцию так, как вы хотите ее использовать.источник
Системный вызов это!
Тогда просто прочитайте файл.
РЕДАКТИРОВАТЬ: Этот ответ следует считать взломать, но он действительно работает (хотя и в зависимости от платформы), если у вас нет доступа к более элегантным решениям.
источник
Поскольку файлы и подкаталоги каталога обычно хранятся в древовидной структуре, интуитивно понятным способом является использование алгоритма DFS для рекурсивного обхода каждого из них. Вот пример в операционной системе Windows с использованием основных файловых функций в io.h. Вы можете заменить эти функции на другой платформе. Что я хочу выразить, так это то, что основная идея DFS прекрасно соответствует этой проблеме.
источник
Я попытался следовать примеру, приведенному в обоих ответах, и, возможно, стоит отметить, что он выглядит так, как будто
std::filesystem::directory_entry
он был изменен, чтобы не иметь перегрузки<<
оператора. Вместо этогоstd::cout << p << std::endl;
я должен был использовать следующее, чтобы иметь возможность скомпилировать и заставить его работать:попытка передать
p
его самостоятельноstd::cout <<
привела к отсутствующей ошибке перегрузки.источник
Основываясь на том, что Herohuyongtao опубликовал и несколько других сообщений:
http://www.cplusplus.com/forum/general/39766/
Каков ожидаемый тип ввода FindFirstFile?
Как конвертировать wstring в строку?
Это решение для Windows.
Так как я хотел передать в std :: string и вернуть вектор строк, мне пришлось сделать пару преобразований.
источник
WIN32_FIND_DATAA
,FindFirstFileA
иFindNextFileA
. Тогда не будет необходимости преобразовывать результат в многобайтовый или ввод в Unicode.Просто то, чем я хочу поделиться и поблагодарить вас за материал для чтения. Поиграйте с функцией, чтобы немного ее понять. Вам может понравиться это. e обозначает расширение, p обозначает путь, а s обозначает разделитель пути.
Если путь пропущен без конечного разделителя, разделитель будет добавлен к пути. Для расширения, если введена пустая строка, функция вернет любой файл, который не имеет расширения в своем имени. Если была введена одна звезда, будут возвращены все файлы в каталоге. Если длина e больше 0, но не является единственной *, то точка e будет добавлена к e, если e не содержала точку в нулевой позиции.
Для возвращаемого значения. Если возвращается карта нулевой длины, то ничего не найдено, но каталог открыт. Если индекс 999 доступен из возвращаемого значения, но размер карты равен только 1, это означало, что возникла проблема с открытием пути к каталогу.
Обратите внимание, что для эффективности эту функцию можно разделить на 3 меньшие функции. Кроме того, вы можете создать функцию вызывающей стороны, которая будет определять, какую функцию она будет вызывать, основываясь на вводе. Почему это более эффективно? Сказано, что если вы собираетесь захватить все, что является файлом, то при использовании этого метода подфункция, созданная для захвата всех файлов, будет просто захватывать все файлы и не должна оценивать какие-либо другие ненужные условия при каждом обнаружении файла.
Это также относится к случаям, когда вы получаете файлы, которые не имеют расширения. Специальная встроенная функция для этой цели будет оценивать погоду только в том случае, если найденный объект является файлом, а затем, будет ли в имени файла точка.
Экономия может быть невелика, если вы только читаете каталоги с небольшим количеством файлов. Но если вы читаете большое количество каталогов или если каталог содержит пару сотен тысяч файлов, это может быть огромной экономией.
источник
источник
Это сработало для меня. Он записывает файл только с именами (без пути) всех файлов. Затем он читает этот текстовый файл и печатает его для вас.
источник