我怎样才能使 boost::filesystem::path 不区分大小写
how can I make a boost::filesystem::path case insensitive
任何人都可以告诉我如何使 boost::filesystem::path 不区分大小写吗?通常,区分大小写是 native 平台决定,但是对于我的应用程序来说这并不是那么简单,因为路径详细信息是从二进制文件中提取的,应用程序要求是无论如何我在 运行 上的平台,我必须不区分大小写地处理所有路径。
到目前为止我一直这样做的方法是使用 boost::filesystem::path::generic_string() 方法来放置我我正在比较一种通用的字符串格式以进行字典序比较。接下来,我将字符串转换为小写并使用 std::string 函数来执行比较和其他运算符方法。显然这是次优的,因为我希望能够对 路径 而不是 字符串 执行字典序比较。在内部,boost 的路径 operator<() 实现使用了一个聪明的字典路径比较,使用路径的迭代器——这不同于字符串字典顺序比较。
我认为有一些方法可以提供一个特殊的用户定义的字符串类型作为内部表示来提升构造函数中的路径,但我不确定如何做到这一点。通常,这种性质的不区分大小写将通过关联的特征 classes 执行 - 正如您在下面看到的用于 UtlCIString(实用程序不区分大小写的字符串)的不区分大小写的字符串特征字符 class 中所见。如果可以将不同的字符串类型关联为内部字符串 class 我会使用以下内容,但我不确定如何使用:
// case insensitive character traits
// inherited copy (preserves case),
// case insensitive comparison, search
struct traits_nocase : std::char_traits<char>
{
static bool eq(const char& c1, const char& c2) {
return toupper(c1) == toupper(c2);
}
static bool lt(const char& c1, const char& c2) {
return toupper(c1) < toupper(c2);
}
static int compare(const char* s1, const char* s2, size_t N) {
#if defined (_WIN32)
return _strnicmp(s1, s2, N);
#else // POSIX
return strncasecmp( s1, s2, N );
#endif
}
static const char* find(const char* s, size_t N, const char& a) {
for (size_t i = 0; i < N; ++i) {
if (toupper(s[i]) == toupper(a)) {
return s + i;
}
}
return 0;
}
static bool eq_int_type(const int_type& c1, const int_type& c2) {
return toupper(c1) == toupper(c2);
}
};
// string preserves case; comparisons are case insensitive
typedef std::basic_string<char, traits_nocase> UtlCIString;
简答:使用 boost::filesystem::directory_iterator
并自行查找路径。
长答案:不要。
您建议如何处理用户合法地在给定路径中拥有多个名称不区分大小写的文件的情况?
当用户特别告诉您使用这些文件中的 一个 但是,通过您的 超级可靠 假设时,您认为会发生什么了解用户 "wants" 决定使用 other 路径的原因?
为什么你 using/targeting 文件系统区分大小写,如果你认为你不应该这样?
任何人都可以告诉我如何使 boost::filesystem::path 不区分大小写吗?通常,区分大小写是 native 平台决定,但是对于我的应用程序来说这并不是那么简单,因为路径详细信息是从二进制文件中提取的,应用程序要求是无论如何我在 运行 上的平台,我必须不区分大小写地处理所有路径。
到目前为止我一直这样做的方法是使用 boost::filesystem::path::generic_string() 方法来放置我我正在比较一种通用的字符串格式以进行字典序比较。接下来,我将字符串转换为小写并使用 std::string 函数来执行比较和其他运算符方法。显然这是次优的,因为我希望能够对 路径 而不是 字符串 执行字典序比较。在内部,boost 的路径 operator<() 实现使用了一个聪明的字典路径比较,使用路径的迭代器——这不同于字符串字典顺序比较。
我认为有一些方法可以提供一个特殊的用户定义的字符串类型作为内部表示来提升构造函数中的路径,但我不确定如何做到这一点。通常,这种性质的不区分大小写将通过关联的特征 classes 执行 - 正如您在下面看到的用于 UtlCIString(实用程序不区分大小写的字符串)的不区分大小写的字符串特征字符 class 中所见。如果可以将不同的字符串类型关联为内部字符串 class 我会使用以下内容,但我不确定如何使用:
// case insensitive character traits
// inherited copy (preserves case),
// case insensitive comparison, search
struct traits_nocase : std::char_traits<char>
{
static bool eq(const char& c1, const char& c2) {
return toupper(c1) == toupper(c2);
}
static bool lt(const char& c1, const char& c2) {
return toupper(c1) < toupper(c2);
}
static int compare(const char* s1, const char* s2, size_t N) {
#if defined (_WIN32)
return _strnicmp(s1, s2, N);
#else // POSIX
return strncasecmp( s1, s2, N );
#endif
}
static const char* find(const char* s, size_t N, const char& a) {
for (size_t i = 0; i < N; ++i) {
if (toupper(s[i]) == toupper(a)) {
return s + i;
}
}
return 0;
}
static bool eq_int_type(const int_type& c1, const int_type& c2) {
return toupper(c1) == toupper(c2);
}
};
// string preserves case; comparisons are case insensitive
typedef std::basic_string<char, traits_nocase> UtlCIString;
简答:使用 boost::filesystem::directory_iterator
并自行查找路径。
长答案:不要。
您建议如何处理用户合法地在给定路径中拥有多个名称不区分大小写的文件的情况?
当用户特别告诉您使用这些文件中的 一个 但是,通过您的 超级可靠 假设时,您认为会发生什么了解用户 "wants" 决定使用 other 路径的原因?
为什么你 using/targeting 文件系统区分大小写,如果你认为你不应该这样?