Функция boost to_upper в string_algo не учитывает локаль

У меня проблема с функциями в пакете string_algo.

Рассмотрим этот кусок кода:

#include <boost/algorithm/string.hpp>
int main() {
   try{
      string s = "meißen";
      locale l("de_DE.UTF-8");
      to_upper(s, l);
      cout << s << endl;
   catch(std::runtime_error& e){
      cerr << e.what() << endl;
   }

   try{
      string s = "composición";
      locale l("es_CO.UTF-8");
      to_upper(s, l);
      cout << s << endl;
   catch(std::runtime_error& e){
      cerr << e.what() << endl;
   }
}

Ожидаемый результат для этого кода будет:

MEISSEN
COMPOSICIÓN

Однако единственное, что я получаю, это

MEIßEN
COMPOSICIóN

таким образом, ясно, язык не принимается во внимание. Я даже пытаюсь установить глобальную локаль без успеха. Что я могу сделать?

4 ответа

Решение

std::toupper предполагает преобразование 1:1, поэтому нет надежды на случай с ß в SS, Boost.StringAlgo или нет.

Глядя на код StringAlgo, мы видим, что он использует локаль (кажется, за исключением Borland). Итак, для другого случая мне любопытно: каков результат toupper('ó', std::locale("es_CO.UTF-8"))на вашей платформе?

Написание вышесказанного заставляет меня задуматься о другом: какова кодировка строк в ваших источниках? UTF8? В этом случае std::toupper увидит две единицы кода для 'ó', поэтому надежды нет. Latin1? В этом случае использование локали с именем ".UTF-8" является несовместимым.

В дополнение к ответу Эрика Маленфанта - std::locale гранит работает на одного персонажа. Чтобы получить лучший результат, вы можете использовать std::wstring - таким образом, большее количество символов будет преобразовано, но, как вы можете видеть, оно все еще не идеально (пример ß).

Я бы предложил попробовать Boost.Locale (новая библиотека для boost, еще не в boost), которая делает вещи

http://cppcms.sourceforge.net/boost_locale/docs/,

В частности, смотрите http://cppcms.sourceforge.net/boost_locale/docs/index.html которой рассматривается проблема, о которой вы говорите.

Вы можете использовать boost::locale. Вот пример.

В стандартной библиотеке есть std::toupper (который использует boost::to_upper), который работает с одним символом за раз.

Это объясняет, почему ß не работает. Вы не сказали, какую стандартную библиотеку и кодовую страницу вы используете, поэтому я не знаю, почему - не сработало.

Что произойдет, если вы используете вместо этого wstring?

Другие вопросы по тегам