Chinaunix首页 | 论坛 | 博客
  • 博客访问: 485022
  • 博文数量: 142
  • 博客积分: 4126
  • 博客等级: 上校
  • 技术积分: 1545
  • 用 户 组: 普通用户
  • 注册时间: 2008-02-22 10:03
文章分类

全部博文(142)

文章存档

2011年(8)

2010年(7)

2009年(64)

2008年(63)

我的朋友

分类:

2008-12-10 17:18:02

1.1.1 提出问题
 
你想要打印一个字符的本地编码值,或者你想通过提供编码的数字打印字符。

1.1.2 解决方案
 
使用ord函数把一个字符转换成相应的数字,或者使用chr函数吧一个数字转换成它对应的字符:

 

$num = ord($char);
$char = chr($num);

在printf和sprintf函数的%c格式化串也可以将一个数字转换成一个字符:

 

$char = sprintf("%c", $num); # 比chr($num)慢一些

printf("Number %d is character %c\n", $num, $num);

使用pack和unpack函数的一个C*模板可以快速的转换很多8比特的数据;同样的,使用U*模板可以处理unicode字符。

 

@bytes = unpack("C*", $string);
$string = pack("C*", @bytes);

$unistr = pack("U4",0x24b6,0x24b7,0x24b8,0x24b9);
@unichars = unpack("U*", $unistr);

1.1.3讨论

那些低层次的无类型的编程语言比如汇编,是把字符跟数字看成是可以互相替换的,而Perl不是。Perl是把字符串跟数字看成是可以互相替换的。这意味着你不能直接在字符跟数字之间互相赋值,Perl提供了Pascal语言里面的chr跟ord函数来互相转换字符跟数字:

 

$value = ord("e"); # 值:101

$character = chr(101); # 值: "e"

一个字符,看起来就跟长度只有1的字符串一样,你只需要直接print就得到了一个字符串,又或者在printf跟sprintf中使用%s的格式。%c格式在printf跟sprintf中可以把一个数字转换成一个字符,你在打印一个字符的时候,就没有必要使用%c这个格式了,因为它本身已经是字符格式了,没有必要再转换一次。

 

printf("Number %d is character %c\n", 101, 101);

pack, unpack, chr, 和ord 都比sprintf快。下面是pack跟unpack的一些例子:

@ascii_character_numbers = unpack("C*", "sample");
print "@ascii_character_numbers\n";
# $>115 97 109 112 108 101


$word = pack("C*", @ascii_character_numbers);
$word = pack("C*", 115, 97, 109, 112, 108, 101); # same

print "$word\n";
# $>sample


#把字符串'HAL'转换成’IBM


$hal = "HAL";
@byte = unpack("C*", $hal);
foreach $val (@byte) {
    $val++; # 给每一个值加一

}
$ibm = pack("C*", @byte);
print "$ibm\n"; # 打印 "IBM"

对于那些单字节的字符数据,比如ASCII或者各种各样的ISO 8859字符集里面的字符,ord函数会返回一个0到255的数字。这些字符对应于C语言里面的unsigned char的数据类型。

当然Perl做的不仅仅是这样,它内嵌了支持了Unicode: 通用字符编码。如果你在chr中,或者在sprintf "%c"时,或者在pack "U*"时传给了它们一个大于255的参数,它们都会返回一个Unicode字符串。

下面是Unicode的一些类似的例子:

@unicode_points = unpack("U*", "fac\x{0327}ade");
print "@unicode_points\n";
# $>102 97 99 807 97 100 101


$word = pack("U*", @unicode_points);
print "$word\n";
# $>fa?ade


$value = ord("马");
print $value;

如果你仅仅是想把这些字符的数值打印出来,你甚至不需要用到unpack。Perl的printf跟sprintf函数可以识别v修饰符(v modifier):

 

printf "%vd\n", "fac\x{0327}ade";
# $>102.97.99.807.97.100.101


printf "%vx\n", "fac\x{0327}ade";

字符串里面每个字符的数值(Unicode的术语称之为code point)被一个.分隔符分割开来。

1.2.4 参考

chr, ord, printf, sprintf, pack, 和 unpack 函数的详细资料可以在 perlfunc(1) 和大骆驼书的第29章找到。

阅读(457) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~