Файловая система имеет класс с именем directory_iterator, который использует стандартную семантику итераторов, подобную применяемой для стандартных контейнеров, чтобы можно было использовать итераторы как указатели на элементы каталога. Однако в отличие от стандартных контейнеров здесь нет функции-члена end, представляющей элемент, следующий за последним элементом (т.е. vector::end). Вместо этого, если вы создаете итератор каталога directory_iteratorпри помощи стандартного конструктора, он предоставляет конечный маркер, который вы можете использовать в операциях сравнения для определения момента завершения просмотра каталога. Поэтому используйте следующий оператор.
directory_iterator end;
Затем вы можете создать итератор для вашего пути и следующим образом сравнивать его с маркером конца.
for (directory_iterator it(fullPath); it != end; ++it) {
// выполнить любые действия с *it
std::cout << it->leaf();
}
Функция-член leafвозвращает строку, представляющую конечный элемент пути, а не весь путь, который вы можете получить, вызывая функцию-член string.
Если вам требуется обеспечить переносимость, но по каким-то причинам вы не можете использовать библиотеки Boost, обратите внимание на исходный код Boost. Он содержит операторы #ifdef, которые учитывают (по большей части) отличия среды Windows и ОС, использующих интерфейс Posix, и в частности отличия в представлении путей, например буквы дисководов и имена устройств.
Смотри также
Рецепты 10.10 и 10.11.
10.13. Извлечение расширения файла из строки
Проблема
Имеется имя файла или полный путь и требуется получить расширение файла, которое является частью имени файла, расположенной за последней точкой. Например, в именах файлов src.cpp , Window.class и Resume.doc расширениями файла являются соответственно .cpp , .class и .doc .
Решение
Преобразуйте имя файла или путь к нему в строку string, используйте функцию-член rfindдля определения позиции последней точки и возвратите то, что находится за ней. Пример 10.20 показывает, как это можно сделать.
Пример 10.20. Получение расширения файла из его имени
#include
#include
using std::string;
string getFileExt(const string& s) {
size_t i = s.rfind('.', s.length());
if (i ! = string::npos) {
return(s.substr(i+1, s.length() - i));
}
return("");
}
int main(int argc, char** argv) {
string path = argv[1];
std::cout << "The extension is \"" << getFileExt(path) << "\"\n";
}
Обсуждение
Для получения расширения из имени файла достаточно лишь найти позицию последней точки «.» и выделить все, что находится справа от нее. Стандартный класс string, определенный в , содержит функции, которые могут выполнить обе эти операции: rfindи substr.
rfindвыполнит поиск ( в обратном направлении ) того, что вы передаете ей в первом аргументе (символ типа charв данном случае), начиная с позиции, указанной вторым аргументом, и возвращает позицию, в которой найден указанный объект. Если поиск завершился неудачей, rfindвозвратит string::npos. Функция substrтакже имеет два аргумента. Первый аргумент содержит позицию первого копируемого элемента, а второй аргумент — количество копируемых символов.
Стандартный класс строки содержит несколько функций-членов, выполняющих поиск. См. рецепт 4.9, в котором более детально обсуждается поиск строк.
Смотри также
Рецепты 4.9 и 10.12.
10.14. Извлечение имени файла из полного пути
Проблема
Имеется полный путь к файлу, например d:\apps\src\foo.с , и требуется получить имя файлa, foo.с .
Решение
Примените подход, который использовался в предыдущем рецепте, и используйте функции rfindи substrдля поиска и получения из полного пути то, что вам нужно. Пример 10.21 показывает, как это можно сделать.
Пример 10.21. Извлечение имени файла из полного пути
#include
#include
using std::string;
string getFileName(const string& s) {
char sep = '/';
#ifdef _WIN32
sep = '\\';
#endif
size_t i = s.rfind(sep.s.length());
if (i ! = string::npos) {
return(s.substr(i+1, s.length( ) - i));
}
return("");
}
int main(int argc, char** argv) {
string path = argv[1];
std::cout << "The file name is \"" << getFileName(path) << "\"\n";
}
Обсуждение
См. предыдущий рецепт, в котором приводится детальное описание функций rfindи substr. Стоит отметить только то, что вы уже, по-видимому, заметили в примере 10.21: в Windows в качестве разделителя используется обратный слеш вместо прямого, поэтому я добавил оператор #ifdefдля установки требуемого разделителя элементов пути.
Читать дальше