Я читал документация для std::tolower
на cppreference.com:
Преобразует данный символ в нижний регистр в соответствии с правилами преобразования символов, определенными в настоящее время установленным языковым стандартом C.
В локали «C» по умолчанию следующие заглавные буквы ABCDEFGHIJKLMNOPQRSTUVWXYZ заменяются соответствующими строчными буквами abcdefghijklmnopqrstuvwxyz.
Как это поведение может измениться в разных регионах?
Собственно, сам пример на сайте показывает разницу:
#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), и поэтому его значение меняется в зависимости от локали, на которую вы переключаетесь:
´
и, следовательно, не изменяется при переходе от верхнего к нижнемуŽ
и, следовательно, меняется на ž
(0xb8 в этой локали) при переходе от верхнего к нижнемуВы могли бы подумать, что в мире после Unicode это было бы неактуально, но многие еще не перешли на Unicode …
Это может измениться двумя способами:
Также обратите внимание, что положение не-ASCII символов в наборе символов может зависеть от локали, поскольку локаль также определяет используемый набор символов. Однако, даже если вы работаете исключительно в Unicode (например, используете исключительно локали UTF-8), у вас все еще есть различия, перечисленные выше.