C ++相当于MATLAB的“fileparts”函数

时间:2011-02-04 19:16:22

标签: c++ matlab file-io

在MATLAB中有一个很好的函数叫做fileparts,它接受一个完整的文件路径并将其解析为路径,文件名(没有扩展名)和扩展名,如下面的例子所示:

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

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

>> pathstr = H:\user4\matlab

>> name = classpath

>> ext = .txt

所以我想知道在我可以使用的任何标准C ++或C库中是否存在等效函数?或者我自己必须实现这个?我意识到这很简单,但我想如果已经有一些预制的东西会更好。

感谢。

5 个答案:

答案 0 :(得分:5)

boost库有一个file system组件“basic_path”,允许您使用迭代器来发现文件名中的每个组件。这样的组件将是特定于操作系统的,我相信你需要为Windows,Linux等单独编译boost。

答案 1 :(得分:3)

我刚写了这个简单的函数。它的行为类似于Matlab的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 :(得分:2)

与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);

答案 3 :(得分:1)

一些可能的解决方案,具体取决于您的操作系统:

答案 4 :(得分:1)

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;
}