Есть ли iswalnum без привязки к локали.
От: Went  
Дата: 12.01.21 15:19
Оценка:
Здравствуйте. Необходимо ограничить ввод пользователя только буквами и цифрами (на вход идут UTF-16 символы).
Раньше использовал iswalnum и все было хорошо. Но внезапно обнаружил, что на MacOSX эта функция перестала пропускать русские буквы. Почитал документацию — якобы, поведение зависит от текущей локали. И можно сделать так:
int main()
{
    wchar_t c = L'\u13ad'; // the Cherokee letter HA ('Ꭽ')
 
    std::cout << std::hex << std::showbase << std::boolalpha;
    std::cout << "in the default locale, iswalnum(" << (std::wint_t)c << ") = "
              << (bool)std::iswalnum(c) << '\n';
    std::setlocale(LC_ALL, "en_US.utf8");
    std::cout << "in Unicode locale, iswalnum(" << (std::wint_t)c << ") = "
              << (bool)std::iswalnum(c) << '\n';
}

и все заработает.
Не заработало. Во-первых, мне не хочется переключать локаль в иную, чем стоит по умолчанию, во-вторых, даже с указанием локали "en_US.utf8" русские буквы ей все равно не нравятся (я вижу, что там en, но и "ru_RU.utf8" тоже не имеет эффекта). Да и при чем тут локаль, строго говоря? Мне просто нужно узнать класс символа, который однозначно определяется этими двумя байтами (про экзотику не будем), и символ "ъ" будет буквой хоть в Испании, хоть в Китае.
Или это глюк маковской стандартной библиотеки?
Re: Есть ли iswalnum без привязки к локали.
От: watchmaker  
Дата: 12.01.21 16:50
Оценка: 4 (1)
Здравствуйте, Went, Вы писали:

W>Во-первых, мне не хочется переключать локаль в иную, чем стоит по умолчанию,

Заметь, что когда программа стартует, у неё локаль "C". Это не та локаль, которая стоит у пользователя.
И в локале "C" нет вообще никакой кириллицы или юникода.
Программы, которым хочется использовать пользовательскую не зря вызывают при старте setlocale(LC_ALL, "").


W> Да и при чем тут локаль, строго говоря? Мне просто нужно узнать класс символа, который однозначно определяется этими двумя байтами (про экзотику не будем), и символ "ъ" будет буквой хоть в Испании, хоть в Китае.

Код символа в юникоде — да, не зависит и определяется номером.
Только вот что будет читаться или писаться в поток wcin/wcout определяется локалью.
То есть это разные задачи.
Если нужно определить класс юникод-символа по его же номеру в юникод-таблице, то нужно брать библиотеку для работы с юникодом.


W>Или это глюк маковской стандартной библиотеки?

Можно так сказать.
https://stackoverflow.com/questions/11107608/whats-wrong-with-c-wchar-t-and-wstrings-what-are-some-alternatives-to-wide/11107667#11107667
В некотором смысле wchar_t сломан везде. Он не подходит для работы с юникодом. Этот тип как раз про локали.
Нужно использовать ui32 для codepoints, и что-нибудь вроде utf8 для строк (ну или utf16, utf32, где надо).
Re: Есть ли iswalnum без привязки к локали.
От: Bill Baklushi СССР  
Дата: 12.01.21 16:57
Оценка:
Went:

W>во-вторых, даже с указанием локали "en_US.utf8" русские буквы ей все равно не нравятся

Бросается в глаза, что тут ты указываешь utf8, так где фактически utf16 (или utf32).
По дефолтной локали ничего не могу сказать, не знаю.
Модератор-националист Kerk преследует оппонентов по политическим мотивам.
Отредактировано 12.01.2021 17:28 Bill Baklushi . Предыдущая версия .
Re[2]: Есть ли iswalnum без привязки к локали.
От: Went  
Дата: 12.01.21 19:15
Оценка:
Здравствуйте, Bill Baklushi, Вы писали:
W>>во-вторых, даже с указанием локали "en_US.utf8" русские буквы ей все равно не нравятся
BB>Бросается в глаза, что тут ты указываешь utf8, так где фактически utf16 (или utf32).
BB>По дефолтной локали ничего не могу сказать, не знаю.
Ну, я скопировал пример с cppreference
Re: Есть ли iswalnum без привязки к локали.
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 12.01.21 19:24
Оценка: 13 (2)
Здравствуйте, Went, Вы писали:

W>Не заработало. Во-первых, мне не хочется переключать локаль в иную, чем стоит по умолчанию, во-вторых, даже с указанием локали "en_US.utf8" русские буквы ей все равно не нравятся (я вижу, что там en, но и "ru_RU.utf8" тоже не имеет эффекта). Да и при чем тут локаль, строго говоря? Мне просто нужно узнать класс символа, который однозначно определяется этими двумя байтами (про экзотику не будем), и символ "ъ" будет буквой хоть в Испании, хоть в Китае.

W>Или это глюк маковской стандартной библиотеки?

Они все такие — у них другие цели.
По-моему, тебе нужно подключить ICU.
Она популярна, так что будет уже установлена почти наверняка.
The God is real, unless declared integer.
Re[3]: Есть ли iswalnum без привязки к локали.
От: Bill Baklushi СССР  
Дата: 12.01.21 19:27
Оценка:
Went:

BB>>Бросается в глаза, что тут ты указываешь utf8, так где фактически utf16 (или utf32).

W>Ну, я скопировал пример с cppreference

Думал, что я окончательно разобрался с юникодами, а оказалось, что нифига подобного
Может это специфический косяк макоси?..

Интуиция подсказывет, что wchar_t-функции должны работать с utf16 или utf32 в зависимости от ширины wchar_t...
Как на самом деле уже сомневаюсь...
Модератор-националист Kerk преследует оппонентов по политическим мотивам.
Re[2]: Есть ли iswalnum без привязки к локали.
От: Went  
Дата: 13.01.21 08:27
Оценка:
Здравствуйте, watchmaker, Вы писали:

W>Заметь, что когда программа стартует, у неё локаль "C". Это не та локаль, которая стоит у пользователя.

W>И в локале "C" нет вообще никакой кириллицы или юникода.
Ну, в винде же с локалью по умолчанию iswalnum русские буквы пропускает... То есть это глюк винды? А макось делает все верно?

W>Программы, которым хочется использовать пользовательскую не зря вызывают при старте setlocale(LC_ALL, "").

Этот код установит пользовательскую? Но, все равно, я так понимаю, это мне не поможет? Даже если главный язык стоит русским?

W>То есть это разные задачи.

W>Если нужно определить класс юникод-символа по его же номеру в юникод-таблице, то нужно брать библиотеку для работы с юникодом.
То есть iswalnum и прочие подобные функции для моей задачи не годятся? Понятно.

W>https://stackoverflow.com/questions/11107608/whats-wrong-with-c-wchar-t-and-wstrings-what-are-some-alternatives-to-wide/11107667#11107667

Постараюсь разобраться, спасибо

W>В некотором смысле wchar_t сломан везде. Он не подходит для работы с юникодом. Этот тип как раз про локали.

W>Нужно использовать ui32 для codepoints, и что-нибудь вроде utf8 для строк (ну или utf16, utf32, где надо).
Это теоретически или практически? В вижуале wchar_t имеет размер в 16бит. Разве этого недостаточно для того, чтобы записать любую реальную букву? Ну, пускай, с небольшими ограничениями? Или есть опасность, что где-то wchar_t будет вообще 8бит?
Re[3]: Есть ли iswalnum без привязки к локали.
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 13.01.21 09:15
Оценка:
Здравствуйте, Went, Вы писали:

W>Это теоретически или практически? В вижуале wchar_t имеет размер в 16бит. Разве этого недостаточно для того, чтобы записать любую реальную букву? Ну, пускай, с небольшими ограничениями?


1. "Реальные" помещались в 16 бит до массового наступления эпохи эмодзи в юникоде. С ними, то есть последние лет 5 выход за пределы 0-FFFF это скорее норма, чем исключение.

В пару суррогатов это, конечно, влезет, но уже не столь просто.

2. Вы что имели в виду под "буква"? Цифры уже не в счёт? Символ, если быть точным, с самого начала не влазил — за счёт модификаторов: Á̃̈̌ это одна символ (и таки буква), но пять пунктов UTF-16.
Если считаете это не проблемой — учтите, что, например, софт под всякими макосями любит генерировать Й как Й (в два пункта). И это уже буква. Если U+0418 ещё таким простым iswalnum() будет принят, то идущий за ним U+0306 — уже нет.

W> Или есть опасность, что где-то wchar_t будет вообще 8бит?


Не в этом дело
The God is real, unless declared integer.
Отредактировано 13.01.2021 9:17 netch80 . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.