在许多编程语言中,都有一对函数chr()
和ord()
,用于数字与字符值之间的转换。在某些语言中,ord()
被称为asc()
。
Ruby拥有Integer#chr
函数,非常好用:
>> 65.chr
A
好的,但是如何反过来呢?
"A".each_byte do |byte|
puts byte
end
输出:
65
这差不多是我想要的。但我真的想避免使用循环 - 我正在寻找一些在声明 const
时足够简短易读的东西。
"A".ord #=> 65
puts ?A
'A'[0]
在Ruby 1.9中,这种行为已经发生了改变,上述代码都会输出"A"。在Ruby 1.9中正确的写法是:
The behavior has changed in Ruby 1.9, both of the above will produce "A" instead. The correct way to do this in Ruby 1.9 is:
'A'[0].ord
不幸的是,在Ruby 1.8中并不存在ord
方法。
尝试:
'A'.unpack('c')
我想赞同dylanfm和AShelley的评论,并补充[0]:
'A'.unpack('C')[0]
unpack调用返回一个包含单个整数的数组,这并不总是被接受为整数所需的内容:
$ ruby -e 'printf("0x%02X\n", "A".unpack("C"))' -e:1:in `printf': can't convert Array into Integer (TypeError) from -e:1 $ ruby -e 'printf("0x%02X\n", "A".unpack("C")[0])' 0x41 $
我正在尝试编写适用于Ruby 1.8.1、1.8.7和1.9.2的代码。
编辑以使用大写字母C传递给unpack,因为在我的平台上运行时,C的char是有符号的,而unpack("c")给我-1,而ord()给我255。
在按照RFCs准备纯Ruby版本的Stringprep时,我遇到了这个问题。
请注意,chr
在[0,255]之外会失败,因此请使用1.9.x - 2.1.x可移植的替代方法:
[22] pry(main)> "\u0221".ord.chr
RangeError: 545 out of char range
from (pry):2:in 'chr'
[23] pry(main)> x = "\u0221".unpack('U')[0]
=> 545
[24] pry(main)> [x].pack('U')
=> "ȡ"
[25] pry(main)>
puts 'Az'[0]
=> 65
puts 'Az'[1]
=> 122
"A".bytes
。65.chr.ord
'a'.ord.chr
你觉得怎么样?
puts ?A
我正在编写适用于1.8.6和1.9.3的代码,但是我无法让这些解决方案在两个环境中都起作用 :(
然而,我找到了另一个解决方案: http://smajnr.net/2009/12/ruby-1-8-nomethoderror-undefined-method-ord-for-string.html
那对我也没用,但我为我的使用进行了调整:
unless "".respond_to?(:ord)
class Fixnum
def ord
return self
end
end
end
完成这个步骤后,以下内容将在两个环境中都能正常工作。
'A'[0].ord
"A".unpack("C")[0]
,那是针对Ruby 1.8.1、Ruby 1.8.7和Ruby 1.9.2。在你的环境中它失败了吗?出现了什么样的错误? - RJHunterself.status = tagAccountString[4].unpack('C')[0]
在1.8.6中我得到了
Exception undefined method 'unpack' for 0:Fixnum processing main buffered tag data - exit
以下代码(使用我的解决方案)在两个环境中都有效。
self.status = tagAccountString[4].ord
任何建议(例如更好的解决方案)都非常欢迎。 - hantscolintagAccountString[4]
在新版本的 Ruby 中返回一个字符串,但在 Ruby 1.8 中返回一个 Fixnum。这就是为什么你看到了错误 undefined method unpack for 0:Fixnum
。你可以使用 status = tagAccountString[4,1].unpack('C')[0]
或者 status, = tagAccountString.unpack('xxxxC')
,如果你总是想忽略前四个字符并转换下一个字符。 - RJHunter