C++ 使用boost从文件路径提取直接父目录

C++ 使用boost从文件路径提取直接父目录,c++,boost,std,boost-filesystem,C++,Boost,Std,Boost Filesystem,假设我有 String t = "c:/foo/foo1/foo2/foo3/file.txt" 我想提取“foo3/file.txt” 我如何做到这一点(使用boost或std) 以下是我到目前为止一直在尝试的: boost::filesystem::path pathToObject(t); 当然,使用pathToObject.filename()我可以提取文件名。我一直在玩t.find_last_of(“/”),但我真的需要像t.find_second_to_last_of(“/”),

假设我有

String t = "c:/foo/foo1/foo2/foo3/file.txt"
我想提取
“foo3/file.txt”

我如何做到这一点(使用boost或std)

以下是我到目前为止一直在尝试的:

boost::filesystem::path pathToObject(t);

当然,使用
pathToObject.filename()
我可以提取文件名。我一直在玩
t.find_last_of(“/”)
,但我真的需要像
t.find_second_to_last_of(“/”)
,提取这样的路径很奇怪。也许你在寻找一条相对的路径?boost文件系统有一个工具来实现这一点。一定要好好看一看。但要回答你的问题:

namespace bfs= boost::filesystem;
    int main( ) {
        bfs::path path( "c:/foo/foo1/foo2/foo3/file.txt" );
        bfs::path target( path );
        target.remove_filename( );
        target= target.filename( ) / path.filename( );
        std::cout << target << std::endl;
    }
namespace bfs=boost::filesystem;
int main(){
路径路径(“c:/foo/foo1/foo2/foo3/file.txt”);
bfs::路径目标(path);
target.remove_filename();
target=target.filename()/path.filename();

std::cout我手头没有一个编译器来测试它,但是根据这里的示例,这段代码基本上应该可以工作,或者为您指出正确的方向。即使从我在这里写的内容来看,它可能也会简化一点

path p1( "c:/foo/foo1/foo2/foo3/file.txt" );
path p2;
for (path::iterator it(p1.end()), int i = 0; it != p1.begin() && i < 2; --it, ++i) {
  path temp = p2;
  p2 = it;
  p2 /= temp;
}
路径p1(“c:/foo/foo1/foo2/foo3/file.txt”); 路径p2; 对于(path::iterator it(p1.end()),int i=0;it!=p1.begin()&&i<2;--it,++i){ 路径温度=p2; p2=它; p2/=温度; }
字符串::find_last_of
有一个用于指定要查看字符串的深度的

所以你可以定义

size_t second_to_last = t.find_last_of("/", t.find_last_of("/")-1);
std::string file_with_parent = t.substr(second_to_last+1);
第二个参数告诉他只在最后一个
/
之前搜索

警告:如果你有
“C:/bli/bla//blubb.txt”
之类的东西,这可能与你想要的有所不同。一般来说,路径可能会很复杂和混乱,试图用字符串操作来克服它们只会对表现良好的输入有效,而这通常是无法假设的

因此,我建议使用适当的工具来完成这项工作。*但由于问题表明,
find_last_of
无法完成这项工作,我觉得有必要提醒人们,标准设施并不像许多人认为的那样完全无效


*我怀疑boost path库是其中之一,但我从未使用过它。

以下是我最终使用的解决方案:

std::string t = pathObject.parent_path().filename().string();
t.append("/");
t.append(pathObject.filename().string());

使用
parent\u path
只给了我路径。然后我使用
filename
只提取目录。然后我附加子目录的
filename

以下方法返回立即的父目录

#include <string>
string getParentDirectory(string& filePath)
{
    if (filePath.empty() == false)
    {
        size_t toPos = filePath.find_last_of('\\') - 1;
        if (toPos != string::npos)
        {
            size_t fromPos = filePath.find_last_of('\\', toPos);
            if (fromPos != string::npos)
            {
                return filePath.substr(fromPos + 1, toPos - fromPos);
            }
        }
    }

    return "";
}

int main() 
{
    string str = "D:\\Devs\\Test\\sprite.png";

    string parentDir = getParentDirectory(str);
    return 0;
}
#包括
字符串getParentDirectory(字符串和文件路径)
{
if(filePath.empty()==false)
{
size\u t toPos=filePath.find\u last\u of('\\')-1;
if(拓扑!=字符串::npos)
{
size\u t fromPos=filePath。查找('\\',toPos)中的最后一个;
if(fromPos!=字符串::npos)
{
返回filePath.substr(fromPos+1,toPos-fromPos);
}
}
}
返回“”;
}
int main()
{
string str=“D:\\Devs\\Test\\sprite.png”;
字符串parentDir=getParentDirectory(str);
返回0;
}

它打印parentDir的值为“Test”。

您尝试了什么?为什么不参加考试?感谢您的回答和我的@joshj777。以下是我最终使用的解决方案:std::string t=pathObject.parent_path().filename().string();t.append(“/”;t.append(pathObject.filename().string());您应该接受下面的一个答案。(它可以是您自己的,但不一定非得如此。)谢谢!Hermann!长期潜伏者和用户。希望更多地参与。一个已解决的问题而没有被接受的答案会触发我的。那么,你能帮我解决这个问题吗?是的,我实际上只是在查找文件的父目录。然后删除
filename
,剩下的
filename
就是你的父目录y、 这就是我发布的代码。这太复杂了。绝对是个坏建议,但它确实有一种奇怪的美这是因为它比大多数其他解决方案可能更通用。这个解决方案可以抽象到路径的n个级别,而不是2个级别,只需要几行代码。我也可以。只需循环到
n
,始终记住
i
最后一个斜杠的位置。对我来说,美妙之处在于使用两个迭代器re我不认为应该使用单一的路径。如果是我,我会将路径对象保留为增强路径。没有必要从一个字符串到另一个路径再到另一个字符串。我在我的答案中添加了一行重要的内容。我喜欢简单性。人们往往会忘记标准库实用程序。但是,如果我想进行路径操作,我个人不会去这里因为在现实生活中,路径是不可预测的nonetheless@sehe小崽子,由于没有人注意到这条消息不可靠,我把它扩展成一个大胆的警告。现在高兴了吗?(=哦,我以前很高兴。我也没有看到太多的反对票,所以你不必担心那么多。安全总比遗憾好。如果有人因为某个白痴盲目复制了我的代码而死亡,我想说“但我警告过他们”。这几乎和没有人会死一样好!而且,我也不知道你所说的“[不是]许多人投了反对票”。