Как заставить кодовый набор cp1252 для выходного файла в perl >=5.18 в Windows 10?

Мне нужно убедиться, что выходной файл, который я создаю с помощью моего perl-скрипта, имеет кодовый набор cp1252, а не UTF-8, потому что он будет использоваться в среде UNIX SQLplus, которая неправильно обрабатывает немецкие "умляуты" при вставке этих значений в базу данных. столбцы (я использую клубнику Perl v5.18 в Windows 10, и я не могу установить NLS_LANG или chcp в среде SQL UNIX).

С помощью этого небольшого тестового сценария я могу воспроизвести, что выходной файл "testfile1.txt" всегда находится в UTF-8, но "testfile2.txt" - это CP1252, как и ожидалось. Как я могу заставить выходные данные для "testfile1.txt" быть также CP1252, даже если в тексте нет "специальных" символов?

#!/usr/bin/env perl -w
use strict;
use Encode;

# the result file under Windows 10 will have UTF-8 codeset
open(OUT,'> testfile1.txt');    
binmode(OUT,"encoding(cp-1252)");
print OUT encode('cp-1252',"this is a test");
close(OUT);

# the result file under Windows 10 will have Windows-cp1252 codeset
open(OUT,'> testfile2.txt');    
binmode(OUT,"encoding(cp-1252)");
print OUT encode('cp-1252',"this is a test with german umlauts <ÄäÜüÖöß>");
close(OUT);

1 ответ

Решение

Я думаю, что ваш вопрос основан на недоразумении. testfile1.txt содержит текст this is a test, Эти символы имеют одинаковую кодировку в ASCII, Latin-1, UTF-8 и CP-1252. testfile1.txt действует во всех этих кодировках одновременно.


Чтобы включить буквальные символы Юникода в ваш исходный код следующим образом:

print OUT encode('cp-1252',"this is a test with german umlauts <ÄäÜüÖöß>");

тебе нужно

use utf8;

на вершине.

Кроме того, не объединяйте слои кодирования в файловых дескрипторах с явными encode() звонки. Либо установите слой кодирования и напечатайте на нем текст Unicode, либо используйте binmode(OUT) и распечатать сырые байты (как возвращено из encode()) к нему.


Кстати, вы не должны использовать -w больше. Это было вытеснено

use warnings;

Прагма.

Точно так же файловые дескрипторы голых слов и открытое с двумя аргументами код до версии 5.6 и не должны использоваться в коде, написанном после 2000 года. (Perl 5.005 и более ранние версии не поддерживали Unicode/ кодировки в любом случае.)

Фиксированная версия вашего кода выглядит следующим образом:

#!/usr/bin/env perl
use strict;
use warnings;
use utf8;

{
    open(my $out, '>:encoding(cp-1252)', 'testfile1.txt') or die "$0: testfile1.txt: $!\n";    
    print $out "this is a test\n";
    close($out);
}

{
    open(my $out, '>encoding(cp-1252)', 'testfile2.txt') or die "$0: testfile2.txt: $!\n";    
    print $out "this is a test with german umlauts <ÄäÜüÖöß>\n";
    close($out);
}
Другие вопросы по тегам