如何在 Windows 10 内为 perl >=5.18 中的输出文件强制代码集 cp1252?

How to force codeset cp1252 for output file in perl >=5.18 within Windows 10?

我需要确保我用 perl 脚本创建的输出文件具有代码集 cp1252 而不是 UTF-8,因为它将在处理德语的 UNIX SQLplus 框架中使用 "umlauts" 将该值插入数据库列时不正确(我在 Windows 10 中使用 strawberry perl v5.18,我无法在 UNIX SQL 环境中设置 NLS_LANG 或 chcp)。

通过这个小测试脚本,我可以重现输出文件 "testfile1.txt" 始终是 UTF-8,但 "testfile2.txt" 是预期的 CP1252。 即使文本中没有 "special" 个字符,我如何强制 "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);

我认为你的问题是基于误解。 testfile1.txt 包含文本 this is a test。这些字符在 ASCII、Latin-1、UTF-8 和 CP-1252 中具有相同的编码。 testfile1.txt 在所有这些编码中同时有效。


要像这样在源代码中包含文字 Unicode 字符:

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/encodings 无论如何。)

您的代码的固定版本如下所示:

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

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

{
    open(my $out, '>encoding(cp-1252)', 'testfile2.txt') or die "[=13=]: testfile2.txt: $!\n";    
    print $out "this is a test with german umlauts <ÄäÜüÖöß>\n";
    close($out);
}