Perl: печать строк Unicode в консоли Windows - PullRequest
8 голосов
/ 21 февраля 2012

Я сталкиваюсь со странной проблемой при печати строк Unicode на консоли Windows *.

Рассмотрим этот текст:

אני רוצה לישון

Intermediary

היא רוצה לישון
אתם, הם
Bye
Hello, world!
test

Предположим, он находится в файле с именем "file.txt".

Когда я захожу *: "введите file.txt", он печатается нормально. Но когда он печатается из программы на Perl, вот так:

 use strict;
 use warnings;
 use Encode;
 use 5.014;
 use utf8;
 use autodie;
 use warnings    qw< FATAL  utf8     >;
 use open        qw< :std  :utf8     >;
 use feature     qw< unicode_strings >;
 use warnings 'all';

 binmode STDOUT, ':utf8';   # output should be in UTF-8
 my $word;
 my @array = ( 'אני רוצה לישון', 'Intermediary',
    'היא רוצה לישון', 'אתם, הם', 'Bye','Hello, world!', 'test');
 foreach $word(@array) {
    say $word;
 }

Строки Unicode (в данном случае иврит) снова появляются каждый раз, частично разбитые, например:

E:\My Documents\Technical\Perl>perl "hello unicode.pl"
אני רוצה לישון
לישון
�ן

Intermediary
היא רוצה לישון
לישון
�ן

אתם, הם
�ם

Bye
Hello, world!
test

(я сохраняю все в UTF-8).

Это очень странно. Есть предложения?

(Это не проблема «Console2» * - та же проблема появляется на «обычной» консоли Windows, только там вы не видите ивритские глифы).


* Использование «Консоли» (также называемой «Консоль2») - это приятная небольшая утилита, которая позволяет работать с Unicode с консолью Windows - см., Например, здесь: http://www.hanselman.com/blog/Console2ABetterWindowsCommandPrompt.aspx

** Примечание: на консоли вы, конечно, должны сказать:

chcp 65001

Ответы [ 4 ]

4 голосов
/ 21 февраля 2012

Вы пробовали решение из perlmonk ?

Также используется :unix, чтобы избежать буфера консоли.

Это код по этой ссылке:

use Win32::API;

binmode(STDOUT, ":unix:utf8");

#Must set the console code page to UTF8
$SetConsoleOutputCP= new Win32::API( 'kernel32.dll', 'SetConsoleOutputCP', 'N','N' );
$SetConsoleOutputCP->Call(65001);

$line1="\x{2554}".("\x{2550}"x15)."\x{2557}\n";
$line2="\x{2551}".(" "x15)."\x{2551}\n";
$line3="\x{255A}".("\x{2550}"x15)."\x{255D}";
$unicode_string=$line1.$line2.$line3;

print "THIS IS THE CORRECT EXAMPLE OUTPUT IN PURE PERL: \n";
print $unicode_string;
3 голосов
/ 22 февраля 2012

Ребята: продолжая изучать этот пост Perlmonks, выясняется, что это еще аккуратнее и приятнее: заменить:
use Win32::API;
и

$SetConsoleOutputCP= new Win32::API( 'kernel32.dll', 'SetConsoleOutputCP', 'N','N' );
$SetConsoleOutputCP->Call(65001);

с:

use Win32::Console;

и

 Win32::Console::OutputCP(65001);

Оставляя все остальное нетронутым.
Это даже больше в духе лаконичности и волшебства Perl.

1 голос
/ 21 февраля 2012

Вы также можете использовать Win32 :: Unicode :: Console или Win32 :: Unicode :: Native для получения печати Unicode на консоли Windows.

0 голосов
/ 14 ноября 2018

Кроме того, это поведение отсутствует при использовании ConEmu , что также обеспечивает надлежащую поддержку Unicode в командной консоли Windows.

...