C ++ эквивалент функции MATLAB "fileparts" - PullRequest
3 голосов
/ 04 февраля 2011

В MATLAB есть хорошая функция, называемая fileparts, которая берет полный путь к файлу и разбирает его на путь, имя файла (без расширения) и расширение, как в следующем примере из документации:

file = 'H:\user4\matlab\classpath.txt';

[pathstr, name, ext] = fileparts(file)

>> pathstr = H:\user4\matlab

>> name = classpath

>> ext = .txt

Так что мне было интересно, есть ли эквивалентная функция в каких-либо стандартных библиотеках C ++ или C, которые я мог бы использовать? Или я должен был бы осуществить это сам? Я понимаю, что это довольно просто, но я решила, что уже есть что-то готовое, что было бы предпочтительнее.

Спасибо.

Ответы [ 5 ]

5 голосов
/ 04 февраля 2011

В библиотеке надстройки есть файловая система , компонент "basic_path", который позволяет использовать итераторы для обнаружения каждого компонента в имени файла.Такой компонент будет зависеть от ОС, и я считаю, что вам нужно отдельно компилировать boost для Windows, Linux и т. Д.

3 голосов
/ 30 апреля 2013

Я только что написал эту простую функцию. Он ведет себя подобно Matlab's fileparts и работает независимо от платформы.

struct FileParts
{
    string path;
    string name;
    string ext;
};

FileParts fileparts(string filename)
{
    int idx0 = filename.rfind("/");
    int idx1 = filename.rfind(".");

    FileParts fp;
    fp.path = filename.substr(0,idx0+1);
    fp.name = filename.substr(idx0+1,idx1-idx0-1);
    fp.ext  = filename.substr(idx1);

    return fp;
}
2 голосов
/ 04 июня 2018

Независимый от платформы способ с C ++ 11 / 14.

#include <experimental/filesystem> 

namespace fs = std::experimental::filesystem;
void fileparts(string full, string& fpath, string& fname, string& fext)
{
    auto source = fs::path(full);
    fpath = source.parent_path().string();
    fname = source.stem().string();
    fext = source.extension().string();
}
...
string fpath, fname, fext;
fileparts(full_file_path,fpath,fname,fext);
1 голос
/ 29 июня 2018

Текстовый подход Ekalic полезен, но он не проверяет на ошибки. Вот тот, который делает, а также работает как с / и \

struct FileParts
{
    std::string path; //!< containing folder, if provided, including trailing slash
    std::string name; //!< base file name, without extension
    std::string ext;  //!< extension, including '.'
};

//! Using only text manipulation, splits a full path into component file parts
FileParts fileparts(const std::string &fullpath)
{
    using namespace std;

    size_t idxSlash = fullpath.rfind("/");
    if (idxSlash == string::npos) {
        idxSlash = fullpath.rfind("\\");
    }
    size_t idxDot = fullpath.rfind(".");

    FileParts fp;
    if (idxSlash != string::npos && idxDot != string::npos) {
        fp.path = fullpath.substr(0, idxSlash + 1);
        fp.name = fullpath.substr(idxSlash + 1, idxDot - idxSlash - 1);
        fp.ext  = fullpath.substr(idxDot);
    } else if (idxSlash == string::npos && idxDot == string::npos) {
        fp.name = fullpath;
    } else if (/* only */ idxSlash == string::npos) {
        fp.name = fullpath.substr(0, idxDot);
        fp.ext  = fullpath.substr(idxDot);
    } else { // only idxDot == string::npos
        fp.path = fullpath.substr(0, idxSlash + 1);
        fp.name = fullpath.substr(idxSlash + 1);
    }
    return fp;
}
1 голос
/ 04 февраля 2011

Некоторые возможные решения в зависимости от вашей ОС:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...