Как меняется поведение std :: tolower в разных локалях?

Я читал документация для std::tolower на cppreference.com:

Преобразует данный символ в нижний регистр в соответствии с правилами преобразования символов, определенными в настоящее время установленным языковым стандартом C.

В локали «C» по умолчанию следующие заглавные буквы ABCDEFGHIJKLMNOPQRSTUVWXYZ заменяются соответствующими строчными буквами abcdefghijklmnopqrstuvwxyz.

Как это поведение может измениться в разных регионах?

0

Решение

Собственно, сам пример на сайте показывает разницу:

#include <iostream>
#include <cctype>
#include <clocale>

int main()
{
unsigned char c = '\xb4'; // the character Ž in ISO-8859-15
// but ´ (acute accent) in ISO-8859-1

std::setlocale(LC_ALL, "en_US.iso88591");
std::cout << std::hex << std::showbase;
std::cout << "in iso8859-1, tolower('0xb4') gives "<< std::tolower(c) << '\n';
std::setlocale(LC_ALL, "en_US.iso885915");
std::cout << "in iso8859-15, tolower('0xb4') gives "<< std::tolower(c) << '\n';
}

Выход:

in iso8859-1, tolower('0xb4') gives 0xb4
in iso8859-15, tolower('0xb4') gives 0xb8

Поскольку язык C не имеет понятия кодировки, char (и, таким образом, char const*) просто байтов. При переключении локали вы переключаете интерпретация из этих байтов, например, здесь байт 0xb4 (180) находится вне диапазона ASCII (0-127), и поэтому его значение меняется в зависимости от локали, на которую вы переключаетесь:

  • в ISO-8859-1 это означает ´и, следовательно, не изменяется при переходе от верхнего к нижнему
  • в ISO-8859-15 это означает Žи, следовательно, меняется на ž (0xb8 в этой локали) при переходе от верхнего к нижнему

Вы могли бы подумать, что в мире после Unicode это было бы неактуально, но многие еще не перешли на Unicode …

5

Другие решения

Это может измениться двумя способами:

  • В этом наборе есть символы, которые также могут быть переведены не на язык Си. Например, в немецком языке буква «Ä» будет преобразована в «ä».
  • Даже для символов в этом наборе строчная версия может отличаться. Например, в турецких локалях строчная версия «I» должна быть не «i», а «ı», в то время как «i» будет производиться как строчный эквивалент «İ».

Также обратите внимание, что положение не-ASCII символов в наборе символов может зависеть от локали, поскольку локаль также определяет используемый набор символов. Однако, даже если вы работаете исключительно в Unicode (например, используете исключительно локали UTF-8), у вас все еще есть различия, перечисленные выше.

2

По вопросам рекламы [email protected]