gpt4 book ai didi

c++ - 如何在 C++ 中比较(目录)路径?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:31:22 27 4
gpt4 key购买 nike

我正在寻找一种方法来检查 2 个字符串在文件系统路径(目录)方面是否相同。例如,此集合中的所有字符串在文件系统路径方面都是相同的:{/x,\x,//x,/x/},但是这两个 - /x/y 不是,即使 /y 是符号链接(symbolic link)到 /x。我要编写的程序应该既适用于 Linux 也适用于 Windows,因此我正在寻找可移植的解决方案。

编辑:

我只使用 boost 的仅 header 库,所以 boost::filesystem 的解决方案对我来说不合适。我知道在 windows API 中有 UrlCompare,在 linux 中有类似的东西吗?

最佳答案

任何非 Boost 解决方案都将涉及系统相关代码(即如果您使用 Boost,则隐藏在 Boost 中)。你必须准确定义你所说的“匹配”是什么意思:应该"./MyFile.xxx""MyFile.xxx"比较相等?怎么样"aaa/.../MyFile.xxx""MyFile.xxx"

我处理这个问题的方法是定义一个有两个数据成员的类,一个std::string带有“前缀”(总是在 Unix 中为空)和一个 std::vector<std::string>与所有的路径元素。这门课会被必要的比较所淹没功能,并将使用系统相关代码来实现构造器;构造函数本身将在源文件中,而源文件将包含一个机器相关的头文件(通常通过使用每个变体的单独目录,并通过方式选择标题的 -I/I指定要使用的目录)。那种东西这可能会进入标题:

inline bool
isPathSeparator( char ch )
{
return ch == '/';
}

std::string
getHeader( std::string const& fullPathName )
{
return "";
}

bool
charCompare( char lhs, char rhs )
{
return lhs < rhs;
}

bool
charMatch( char lhs, char rhs )
{
return lhs == rhs;
}

对于 Unix,具有:

inline bool
isPathSeparator( char ch )
{
return ch == '/' || ch == '\\';
}

std::string
getHeader( std::string const& fullPathName )
{
return fullPathName.size() > 2 && fullPathName[1] == ':'
? fullPathName.substr( 0, 2 )
: std::string();
}

bool
charCompare( char lhs, char rhs )
{
return tolower( (unsigned char)lhs) < tolower( (unsigned char)rhs );
}

bool
charMatch( char lhs, char rhs )
{
return tolower( (unsigned char)lhs ) == tolower( (unsigned char)rhs );
}

适用于 Windows。

然后构造函数将使用 getHeader初始化标题,和遍历 input.begin() + header.size()input.end() , 打破把字符串向上分解成元素。如果遇到"."的元素,忽略它,对于 ".." 之一, 使用 pop_back()删除顶部路径的元素,前提是路径不为空。之后,就是只是定义要使用的比较器的问题 charComparecharMatch对于 char , 和 std::lexicographical_compare要么 std::equal (在验证大小相等之后)与std::string 的比较器(可能还有你的新类(class))。像这样的东西:

struct FileNameCompare
{
bool operator()( char lhs, char rhs ) const
{
return charCompare( lhs, rhs );
}
bool operator()( std::string const& lhs, std::string const& rhs ) const
{
return std::lexicographical_compare(
lhs.begin(), lhs.end(),
rhs.begin(), rhs.end(),
*this );
}
bool operator()( FileName const& lhs, FileName const& rhs ) const
{
return (*this)( lhs.prefix, rhs.prefix )
|| ( !(*this)( rhs.prefix, lhs.prefix )
&& std::lexicographical_compare(
lhs.elements.begin(), lhs.elements.end(),
rhs.elements.begin(), rhs.elements.end(),
*this ) );
}
};

struct FileNameMatch
{
bool operator()( char lhs, char rhs ) const
{
return charMatch( lhs, rhs );
}
bool operator()( std::string const& lhs, std::string const& rhs ) const
{
return lhs.size() == rhs.size()
&& std::equal( lhs.begin(), lhs.end(), rhs.begin(), *this );
}
bool operator()( FileName const& lhs, FileName const& rhs ) const
{
return (*this)( lhs.prefix, rhs.prefix )
&& lhs.elements.size() == rhs.elements.size()
&& std::equal( lhs.elements.begin(), lhs.elements.end(),
rhs.elements.begin(),
*this );
}
};

应该可以解决问题。 (请记住 operator()( char, char )
const
必须在源文件中;您不能将它们内联到标题中,其中不包括定义的系统相关 header charComparecharMatch .)

关于c++ - 如何在 C++ 中比较(目录)路径?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8504571/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com