如何打印所有CP1252字符?

时间:2010-06-03 08:58:55

标签: perl character-encoding

我无法编写脚本来逐个打印所有Latin-1字符。我该怎么办?

我使用的是以下代码,但它没有给我预期的结果。

foreach $char(0..255)  {
    $hexval   = sprintf("%x",$char);
    $charval = sprintf("%c",%hexval);
    print "$charval";
}

输出应该是:

0065 - e
0066 - f
...
...
007F - character at the step

对于007F之后的所有代码点,它没有给我预期的结果。

3 个答案:

答案 0 :(得分:4)

你的问题标题说你想要“CP1252”但是在你的问题正文中你说你想要“拉丁语-1”。 CP1252和Latin-1不是一回事。 CP1252是基于Latin-1的Microsoft编码,但微软认为无用的某些字符替换为其他字符。

例如在CP1252中,字节0x93是左双引号(“),但在Latin-1中它是不可打印的控制代码。

Perl的内部编码是(几乎但不完全)UTF-8。您可以使用CP1252字节并将其转换为Perl的UTF-8字符串格式,如下所示:

use Encode qw(decode);

my $char = decode("CP1252", "\x80");

CP1252中的字符0x80是欧元符号。在Unicode中,欧元符号为U + 20AC。所以现在$ char将被设置为“\ x {20AC}”。

您的下一个问题是您要“打印”字符。这可能意味着许多事情。问题是你需要从Perl的内部字符表示转换为输出设备所期望的任何编码。

例如我的Linux终端窗口很高兴显示UTF-8,所以我会执行以下操作来打印出欧元字符:

binmode(STDOUT, ':utf8');

print $char, "\n";

但这不太可能在Windows命令提示符下工作。

如果您正在生成HTML输出,那么您应该写出UTF-8并确保您有一个适当的标头来声明编码。这将适用于过去10到15年间发布的几乎所有浏览器。

答案 1 :(得分:2)

foreach (0..255) {
    $hexval = sprintf("%x",$_);
    $charval = sprintf("%c",$_);
    print "$_ => $hexval -> $charval\n";
}

答案 2 :(得分:0)

use strict会给你一个关于原因的好线索。在您的示例的第3行,您有

$charval = sprintf("%c",%hexval);  

但是,您没有为%hexval设置值,您可能需要$hexval。这是第二个错误,您希望格式化原始值$char而不是格式化的十六进制值。

$charval = sprintf("%c", $char);  

这使您的第二行不同,代码可以简化为

use strict;
for my $char (0..255) {
    printf "%c\n", $char;
}