Функция 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 которой рассматривается проблема, о которой вы говорите.
В стандартной библиотеке есть std::toupper (который использует boost::to_upper), который работает с одним символом за раз.
Это объясняет, почему ß не работает. Вы не сказали, какую стандартную библиотеку и кодовую страницу вы используете, поэтому я не знаю, почему - не сработало.
Что произойдет, если вы используете вместо этого wstring?