Как сказал @ikegami, use utf8;
будет декодировать ваш исходный код из UTF-8, так что строковые литералы и другие символы могут быть интерпретированы как задумано. Как и исходный код, входные данные для вашего кода также в байтах, и обычно в кодировке UTF-8, если это текст. Таким образом, в зависимости от того, откуда он исходит, у вас есть несколько вариантов для его преобразования в полезные символы. Ниже перечислены различные варианты, вам нужен только один для определенного потока ввода.
From STDIN:
use open ':std', IN => ':encoding(UTF-8)'; # also affects read filehandles opened in this scope
use open ':std', ':encoding(UTF-8)'; # also affects STDOUT, STDERR, and all filehandles opened in this scope
binmode *STDIN, ':encoding(UTF-8)'; # STDIN only
Или эти переключатели для oneliners:
-CI # STDIN only
-CS # STDIN, STDOUT, STDERR
-Mopen=':std,IN,:encoding(UTF-8)' # equivalent to first "use open" above
From ручки, которые вы открываете сами:
use open IN => ':encoding(UTF-8)'; # all read handles opened in this scope
use open ':encoding(UTF-8)'; # also affects write handles
open my $fh, '<:encoding(UTF-8)', 'example.txt' or die "Failed to open example.txt: $!";
binmode $fh, ':encoding(UTF-8)'; # to set on already opened handle
Или эти переключатели для oneliners:
-Ci # read handles only
-CD # all handles opened
-Mopen='IN,:encoding(UTF-8)' # equivalent to first "use open" above
Указанные выше опции use open
и -C
также применимы к ARGV (ручка, используемая -n
, -p
или оператор <>
/ readline
для чтения имен файлов, переданных в качестве аргументов - это отличается от того, когда он используется для чтения STDIN). Переключатели -C
можно комбинировать, например, -CSD
установит его для STDIN / OUT / ERR, а также для всех открытых дескрипторов.
Наконец, вы можете декодировать сами данные после чтения, а не влиять на какие-либо дескрипторы глобально (ниже, предполагая, что данные в $_
):
utf8::decode($_) or die "Invalid UTF-8"; # in place, does not require "use utf8"
$_ = Encode::decode('UTF-8', $_); # with Encode loaded
$_ = Encode::Simple::decode_utf8($_); # with Encode::Simple loaded
Просто запомните, хотите ли вы выводить такие декодированные символы или символы из литералов с use utf8;
, установленными для вашего исходного кода, STDOUT, STDERR и другие дескрипторы записи требуют такой же обработки, или вам необходимо закодировать данные в UTF-8 перед печатью.
Некоторые полезные ссылки: