1.4 字符跟数值之间互相转换
时间:2006-12-26 来源:xiaoshengcaicai
1.4 字符跟数值之间互相转换
1.4.1 Problem
给定一个字符,你想要打印这个字符对应的数值,或者给定一个数值,你要打印出这个数值对应的字符。
1.4.2 Solution
使用ord把字符转换成数值,使用chr把数值转换成对应的字符。
$num = ord($char);
$char = chr($num);
在printf跟sprintf中使用%c这个格式也可以把一个数值转换成字符。
$char = sprintf("%c", $num); # slower than chr($num)
printf("Number %d is character %c\n", $num, $num);
Number 101 is character e
在pack跟unpack里面使用C*这个Template可以快速的转换很多8 bits字节。同样,转换Unicode字符可以使用U*这个模板。
@bytes = unpack("C*", $string);
$string = pack("C*", @bytes);
$unistr = pack("U4",0x24b6,0x24b7,0x24b8,0x24b9);
@unichars = unpack("U*", $unistr);
1.4.3 讨论
那些低层次的无类型的编程语言比如汇编,是把字符跟数字看成是可以互相替换的,而Perl不是。Perl是把字符串跟数字看成是可以互相替换的。这意味着你不能直接在字符跟数字之间互相赋值,Perl提供了Pascal语言里面的chr跟ord函数来互相转换字符跟数字:
$value = ord("e"); # now 101
$character = chr(101); # now "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++; # add one to each byte value
}
$ibm = pack("C*", @byte);
print "$ibm\n"; # prints "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
如果你仅仅是想把这些字符的数值打印出来,你甚至不需要用到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";
66.61.63.327.61.64.65
字符串里面每个字符的数值(Unicode的术语称之为code point)被一个.分隔符分割开来。
1.4.4 参阅
chr, ord, printf, sprintf, pack, 和 unpack 函数在 perlfunc(1) 跟Programming Perl第29章可以找到。