Update
Как предложил @ikegami, я сообщил об этом как об ошибке.
Рассмотрим следующие программы C и Perl, которые выводят кодировку UTF-8 строки "& alpha; & beta; & gamma;"; на стандартном выходе:
Версия C:
#include <stdio.h>
int main(void) {
/* UTF-8 encoded alpha, beta, gamma */
char x[] = { 0xce, 0xb1, 0xce, 0xb2, 0xce, 0xb3, 0x00 };
puts(x);
return 0;
}
Вывод:
C:\…> chcp 65001 Active code page: 65001 C:\…> cttt.exe αβγ
Perl версия:
C:\…> perl -e "print qq{\xce\xb1\xce\xb2\xce\xb3\n}"
αβγ
�
Из того, что я могу сказать, последний октет 0xb3 выводится снова, на другой строке, который переводится на U+FFFD.
Обратите внимание, что перенаправление вывода устраняет этот эффект.
Я также могу проверить, что это последний октет, повторяющийся:
C:\…> perl -e "print qq{\xce\xb1\xce\xb2\xce\xb3xyz\n}"
αβγxyz
z
С другой стороны, syswrite устраняет эту проблему.
C:\…> perl -e "syswrite STDOUT, qq{\xce\xb1\xce\xb2\xce\xb3xyz\n}"
αβγxyz
Я наблюдал это в окнах cmd.exe на 64-битной Windows 8.1 Pro и 32-битной Windows Vista Home, используя как встроенные perl 5.18.2, так и ActiveState 5.16.3.
Я не вижу проблемы в средах Cygwin, Linux или Mac OS X. Кроме того, Cygwin perl 5.14.4 производит правильный вывод в cmd.exe.
Кроме того, когда кодовая страница установлена в 437, вывод из версий C и Perl идентичен:
C:\…> chcp 437
Active code page: 437
C:\…> cttt.exe
╬▒╬▓╬│
C:\…> perl -e "print qq{\xce\xb1\xce\xb2\xce\xb3\n}"
╬▒╬▓╬│
Что вызывает вывод второго октета дважды при печати из программы perl в cmd.exe, если для кодовой страницы установлено значение 65001?
PS: У меня есть дополнительная информация и скриншоты на в моем блоге. По этому вопросу я попытался перевести все на самые простые случаи.
PPS: вывод \n приводит к чему-то еще более интересному:
C:\…> perl -e "print qq{\xce\xb1\xce\xb2\xce\xb3xyz}"
αβγxyzxyz
C:\…> perl -e "print qq{\xce\xb1\xce\xb2\xce\xb3}"
αβγ�γ�