как я могу сделать boost :: filesystem :: path нечувствительной к регистру

может ли кто-нибудь просветить меня относительно того, как я могу сделать boost :: filesystem :: path нечувствительным к регистру? Обычно чувствительность к регистру - это собственное решение платформы, однако это не так просто для моего приложения, поскольку подробные сведения о пути извлекаются из двоичного файла, а требование приложения состоит в том, что независимо от того, на какой платформе я работаю. работает, я должен обрабатывать все пути нечувствительно к регистру.

До сих пор я делал это с помощью метода boost :: filesystem :: path :: generic_string () для помещения путей, которые я сравниваю, в общий строковый формат для лексикографического сравнения. Затем я преобразовываю строки в нижний регистр и использую функции std :: string для выполнения сравнений и других методов оператора. Очевидно, это неоптимально, поскольку я хотел бы иметь возможность выполнять лексикографические сравнения на путях, а не на строках. Внутренне реализация оператора ‹() пути boost использует умное лексикографическое сравнение путей с использованием итераторов пути - это отличается от строковых лексикографических сравнений.

Я думал, что есть способ предоставить специальный строковый тип, определяемый пользователем, в качестве внутреннего представления для увеличения пути в конструкторе, но я не уверен, как это сделать. Обычно нечувствительность к регистру такого рода будет выполняться через связанные классы признаков - как вы можете видеть ниже в классе символов нечувствительных к регистру строковых признаков, используемом для UtlCIString (служебная нечувствительная к регистру строка). Если бы можно было связать другой строковый тип как внутренний строковый класс, я бы использовал следующее, но я не уверен, как это сделать:

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

person johnco3    schedule 24.01.2015    source источник
comment
Почему голосование против? Я думаю, что это вполне законный вопрос, который был четко сформулирован и, что наиболее важно, на который раньше не было ответа. Я также провел свое исследование и предоставил свои выводы выше вместе с кодом, который может помочь решить проблему?   -  person johnco3    schedule 25.01.2015


Ответы (1)


Краткий ответ: используйте boost::filesystem::directory_iterator и сами находи пути.

Длинный ответ: не надо.

Как вы предлагаете справиться с ситуациями, когда у пользователя законно есть несколько файлов по заданному пути с идентичными именами, кроме регистра?

Как вы думаете, что произойдет, когда пользователь специально скажет вам использовать один из этих файлов, но, благодаря вашим безошибочным предполагаемым знаниям о том, что пользователь "хочет", решил использовать вместо этого другой путь?

Почему вы используете / настраиваете файловую систему с учетом регистра, если считаете, что не следует?

person inetknght    schedule 24.01.2015
comment
Требования приложения состоят в том, что файлы в файловой системе ДОЛЖНЫ обрабатываться без учета регистра. :) с зачеркнутыми словами! Двоичный файл обычно содержит пути и расширения, которые могут иметь регистр, отличный от соответствующих путей и имен файлов в локальной файловой системе. У меня нет контроля над этим, в моем случае это проблема с созданием двоичного файла, которую я должен решить. У меня уже есть неоптимальный обходной путь для этого, но он использует сравнение lex std :: string, и я хотел бы сравнения lex путей (которые уже существуют, хотя и с учетом регистра std :: strings) - person johnco3; 25.01.2015