如何在 c++ 中比较(目录)路径
How to compare (directory) paths in c++?
我正在寻找一种方法来检查 2 个字符串在文件系统路径(目录(方面是否相同。例如,此集合中的所有字符串在文件系统路径方面都是相同的:{ /x
, x
, //x
, /x/
},但这两个 - /x
和 /y
不是,即使/y
是指向/x
的符号链接。我将要编写的程序应该适用于Linux和Windows,所以我正在寻找便携式解决方案。
编辑:
我只使用仅标题的 boost 库,所以boost::filesystem
的解决方案对我来说是不行的。我知道Windows API中有UrlCompare
,有没有类似linux的东西?
任何非 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 );
}
对于视窗。
然后,构造函数将使用 getHeader
来初始化标头,并且遍历input.begin() + header.size()
和input.end()
,打破字符串到元素中。 如果遇到"."
元素,忽略它,对于".."
之一,使用pop_back()
取下顶部元素,前提是路径不为空。 之后,它是只是定义要使用的比较器的问题 charCompare
和 charMatch
用于char
,std::lexicographical_compare
或 std::equal
(在验证大小相等后(与std::string
的比较器(可能还有新的类(。 像这样:
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
必须在源文件中;您不能将它们内联在标头中,它不包括定义 charCompare
和charMatch
。
std::string path1 = "c:\folder\";
std::string path2 = "c:\folder\folder\..\";
boost::filesystem::equivalent(boost::filesystem::path(path1), boost::filesystem::path(path2)
代码返回 true
,因为文件夹实际上是相同的。
使用 boost::filesystem 库 - 它具有路径比较功能。
编辑:您可以尝试apr - 是的,它不C++,但它是便携式的。
在可移植性方面,Boost文件系统库可能很有用(文档链接(。更具体地说:path.hpp
最有用,您可以使用路径比较。
编辑
这个关于 gmane.org 的讨论涉及boost::filesystem
的最小仅标头版本。总结:这不存在。因此,您最终将构建自己的抽象库并为其提供跨平台功能。
在Linux下有dirent.h
,它是一个POSIX C库。对于Windows,您必须使用Win32 API。但是,还有一个所谓的"目录流库",似乎是跨平台的,可在此处获得(网站是德语(。
- 如何在测试运行期间获取资源的目录路径
- 尝试使用堆栈简化目录路径时出现未解决的分段错误
- 包含一批库和目录路径以"Include Additional Directories"视觉C++的任意方法
- 在Windows上,何时有必要将附加到目录路径上,以使_stat成功
- 如何从Windows中的可执行文件中推断出文件/目录路径
- C 获取目录路径,解析文件夹名称和来自Parent Directory的打印文件内容
- 在C 中的FSTREAM中设置默认目录路径
- Visual Studio 2010 包括目录路径
- C++:在比较 boost::文件系统中的路径时,如何忽略第一个目录路径
- 如何将目录路径转换为唯一的数字标识符 (Linux/C++)
- wxWidgets:控件或对话框以选择目录路径
- QT创建者|如何使用行编辑读取目录(路径)
- 提升 API 以检查目录路径是否在 c++ 中的网络上
- C++ Winapi - 获取目录(路径)标识符
- 在C++中获取iPhone目录路径
- 按句柄的目录路径
- CMake包含路径和源路径与Windows目录路径不同
- 如何使用GCC配置Mono Include目录路径
- 查找目录路径
- 如果在目录路径的stat()失败时解释stat()属性,会发生什么?