【问题标题】:C++ equivalent of MATLAB's "fileparts" functionC++ 等效于 MATLAB 的“fileparts”函数
【发布时间】:2011-02-04 19:16:21
【问题描述】:

在 MATLAB 中有一个名为 fileparts 的好函数,它采用完整的文件路径并将其解析为路径、文件名(不带扩展名)和扩展名,如下面的文档示例所示:

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

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

>> pathstr = H:\user4\matlab

>> name = classpath

>> ext = .txt

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

谢谢。

【问题讨论】:

  • 这些函数存在,但它们是操作系统库的一部分,而不是 C++ 标准。 C++ 标准根本没有对文件名作太多说明。您使用的是什么操作系统?
  • basename(3)。不完全是您正在寻找的东西,而是一些东西。
  • 那么我列出的功能应该会有所帮助,它们都是针对 Windows 的。

标签: c++ matlab file-io


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    我刚刚写了这个简单的函数。它的行为类似于 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;
    }
    

    【讨论】:

      【解决方案3】:

      使用 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);
      

      【讨论】:

      • &lt;filesystem&gt; 是 C++17 标准的一部分。像上面一样工作,但删除所有experimental 位。
      【解决方案4】:

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

      【讨论】:

      • 谢谢。我很快就会试试这个。
      【解决方案5】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-02-21
        • 2013-03-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多