Символ Umlaut не принят с клавиатуры (кодовая страница 65001, UTF-8) для чтения perl script

Пожалуйста, позвольте мне сначала заявить, что эта проблема строго связана с оператором алмаза perl, принимающим вход, который был непосредственно введен на клавиатуре.

Если бы я говорил о том, что оператор perl diamond принимает входные данные, которые были переданы по каналам или иным образом из текста из файла, тогда да, это будет дубликат вопроса 519309 - How я читаю Utf-8 с алмазным оператором.

Однако речь идет не о файлах с каналами, а о данных, которые были непосредственно введены на клавиатуре. Поэтому, я утверждаю, этот вопрос не является дубликатом 519309.

Вот подробности моего вопроса:

Я пытаюсь использовать символы умляута ('ä', 'ö', 'ü',...) на моей клавиатуре.

У меня очень простой perl script, который принимает строку с клавиатуры, а затем сразу же распечатывает ее снова для экрана:

Если я использую символы умляута с кодовой страницей 1252, тогда все работает так, как ожидалось:

C:\>chcp 1252 & perl -CS -we"print '*** '; $txt = <>; print '--- ', $txt;"
Page de codes active : 1252
*** ü
--- ü

Однако, если я использую те же символы умляута с кодовой страницей 65001 (UTF-8), тогда я получаю предупреждение неинициализированное значение, а умлаут не принимается:

C:\>chcp 65001 & perl -CS -we"print '*** '; $txt = <>; print '--- ', $txt;"
Page de codes active : 65001
*** ü
Use of uninitialized value $txt in print at -e line 1.
---

Если я подключаю umlaut к моей программе perl, тогда у меня нет проблем:

C:\>chcp 65001 & echo ü | perl -CS -we"print '*** '; $txt = <>; print '--- ', $txt;"
Page de codes active : 65001
*** --- ü

Почему я получаю это предупреждение с кодовой страницей 65001 (UTF-8)?

Я использую Windows 7 x64, с Strawberry Perl 5.22.

Только для записи, если я использую чистые командные команды (то есть я не использую perl), тогда я могу успешно использовать символы умляута с кодовой страницей 65001 (UTF-8).

C:\>chcp 65001 & set /p txt=*** & echo --- %txt%
Page de codes active : 65001
*** ü
--- ü

На самом деле вопрос: почему perl не может принимать символы умляута с помощью клавиатуры с кодовой страницей 65001, тогда как тот же самый ввод на клавиатуре, одна и та же кодовая страница 65001, работает нормально, как команда pure dos batch?

Кажется, что есть что-то принципиально отличное от символов umlaut трубопроводов и ввода символов умлаута непосредственно с клавиатуры.

Почему набирает символ умлаута на клавиатуре, не работая, тогда как то же самое отлично работает как персонаж с каналами?

Ответ 1

Попробуйте изменить шрифт консоли на "Консоль Lucida"

Также вы можете попробовать запустить chcp 65001 в консоли. Эта команда устанавливает символы в UTF-8

Если вы ошибетесь - установите требуемый шрифт в систему.

Подробнее здесь

На самом деле проблема не относится к perl. Он принадлежит терминалу Windows. Попробуйте, как это работает в этой консоли. Вы можете записывать файлы на двоичные данные файла, которые были прочитаны из ввода, и сравнить эти два случая (терминал VS cygwin)

Ответ 2

Это ошибка Microsoft. В Windows APIs ReadFile() и ReadConsoleA() всегда возвращаются 0 байтов, которые читаются (что указывает EOF) на кодовой странице 65001. Подробнее см. этот блог.
Поскольку Microsoft не будет исправлять это, единственный доступный ответ - сообщить разработчикам Perl переключиться на использование ReadConsoleW() и преобразовать результирующие широкие символы в utf-8 с помощью WideCharToMultiByte (CP_UTF8,...).