расширениями файла являются соответственно
Преобразуйте имя файла или путь к нему в строку string
, используйте функцию-член rfind
для определения позиции последней точки и возвратите то, что находится за ней. Пример 10.20 показывает, как это можно сделать.
#include <iostream>
#include <string>
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) << ''
';
}
Для получения расширения из имени файла достаточно лишь найти позицию последней точки «.» и выделить все, что находится справа от нее. Стандартный класс string
, определенный в <string>
, содержит функции, которые могут выполнить обе эти операции: rfind
и substr
.
rfind
выполнит поиск (char
в данном случае), начиная с позиции, указанной вторым аргументом, и возвращает позицию, в которой найден указанный объект. Если поиск завершился неудачей, rfind
возвратит string::npos
. Функция substr
также имеет два аргумента. Первый аргумент содержит позицию первого копируемого элемента, а второй аргумент — количество копируемых символов.
Стандартный класс строки содержит несколько функций-членов, выполняющих поиск. См. рецепт 4.9, в котором более детально обсуждается поиск строк.
Рецепты 4.9 и 10.12.
10.14. Извлечение имени файла из полного пути
Имеется полный путь к файлу, например
Примените подход, который использовался в предыдущем рецепте, и используйте функции rfind
и substr
для поиска и получения из полного пути то, что вам нужно. Пример 10.21 показывает, как это можно сделать.
#include <iostream>
#include <string>
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) << ''
';
}
См. предыдущий рецепт, в котором приводится детальное описание функций rfind
и substr
. Стоит отметить только то, что вы уже, по-видимому, заметили в примере 10.21: в Windows в качестве разделителя используется обратный слеш вместо прямого, поэтому я добавил оператор #ifdef
для установки требуемого разделителя элементов пути.
Класс path
из библиотеки Boost Filesystem позволяет легко получить с помощью функции-члена path::leaf
последний элемент полного пути, которым может быть имя файла или каталога. В примере 10.22 приводится простая программа, которая использует эту функцию, чтобы показать, к чему относится этот путь: к файлу или к каталогу.
#include <iostream>
#include <cstdlib>
#include <boost/filesystem/operations.hpp>
using namespace std;
using namespace boost::filesystem;
int main(int argc, char** argv) {
// Проверка параметров
try {
path p = complete(path(argv[1], native));
cout << p.leaf() << ' is a '
<< (is_directory(p) ? 'directory' : 'file') << endl;
} catch (exception& e) {
cerr << e.what() << endl;
}