Когда я попробовал tolower () с неанглийскими символами в c ++, он не работал нормально. Я искал эту проблему, и я столкнулся с кое-чем о локали, но я не уверен в лучшем решении этого.
Мой пример кода ниже:
printf("%c ",tolower('Ü'));
К сожалению, стандартная библиотека C ++ не имеет достаточной поддержки для изменения регистра всех возможных неанглийских символов (в той части, в которой эти символы вообще имеют варианты регистра). Это ограничение вызвано тем, что стандарт C ++ предполагает, что один символ и его варианты регистра занимают ровно один char
объект (или wchar_t
объект для широких символов) и для неанглийских символов, которые не гарантируются как истинные (также в зависимости от того, как символы кодируются).
Если ваша среда использует однобайтовую кодировку для соответствующих символов, это может дать вам то, что вы хотите:
std::cout << std::tolower('Ü', locale());
С широкими символами вам, вероятно, повезет больше:
std::wcout << std::tolower(L'Ü', locale());
но даже это не даст правильный результат для toupper(L'ß')
, которая будет двухсимвольной последовательностью L"SS"
).
Если вам нужна поддержка всех персонажей, взгляните на библиотека ICU, особенно часть о сопоставлениях случаев
Как показал Барт, C ++ просто не любит многобайтовые кодировки. К счастью, вы можете использовать Boost.Local, чтобы решить эту проблему без особых хлопот. Вот простой пример:
#include <iostream>
#include <locale>
#include <boost/locale.hpp>
int main() {
boost::locale::generator gen;
std::locale loc = gen("en_US.UTF-8");
std::string line;
while (std::getline(std::cin, line))
std::cout << boost::locale::to_lower(line, loc) << '\n';
}
Для компиляции нам нужна ссылка на библиотеку Boost.Locale:
g++ -lboost_locale lower.cpp -o lower
И когда мы выполняем это, мы получаем следующее:
$ ./main <<< 'ICH HÄTTE GERNE EINEN SÜßEN HASEN'
ich hätte gerne einen süßen hasen