论坛首页 编程语言技术论坛

ruby的iconv转码问题

浏览 16510 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2006-09-24  
我用的windows XP,安装的one-click版本
用notepad新建一个文本文件,输入一个字“汉”,然后选择unicode编码保存。
我写得读取文件并显示的代码如下:
require "iconv"
line = File.open('c:\unicode.txt').read
#因notepad存储unicode编码格式的文件时会在文件后加两个字符来标识为unicode编码,故跳过前两个字符
a = line[2..3]
puts a
puts a[0]
puts a[1]
result = Iconv.iconv("GB2312","UTF-16",a)
puts result
puts result[0]
puts result[1]

执行结果显示错误:
C:/temp/code.rb:7:in `iconv': "Il" (Iconv::IllegalSequence)

PS:"汉"的UTF-16的编码为73、108,GB2312的编码为186、186

大家看是什么问题呢?是我的ruby版本问题,还是我选择的编码方式不对?抑或人品问题(有朋友说他在linux上执行没问题)?呵呵
   发表时间:2006-09-24  
试下utf-8一般都是用这个的
0 请登录后投票
   发表时间:2006-09-24  
utf-8也不行。再说这也不是utf-8格式啊
0 请登录后投票
   发表时间:2006-09-24  
还有一个问题 用notepad转成unicode的格式 ,文件好像带有bom信息,你最好用一个专门的转换工具 
0 请登录后投票
   发表时间:2006-09-24  
result = Iconv.iconv("GB2312","UTF-8",a)
0 请登录后投票
   发表时间:2006-09-24  
robbin 写道
result = Iconv.iconv("GB2312","UTF-8",a)

It doesn't work
0 请登录后投票
   发表时间:2006-09-25  
我在Windows/Linux上面试过了,没问题
0 请登录后投票
   发表时间:2006-09-25  
robbin 写道
result = Iconv.iconv("GB2312","UTF-8",a)


这个在Cygwin下也通过
0 请登录后投票
   发表时间:2006-09-25  
搞清楚了,是涉及unicode的big-endian及little-endian的问题
notepad存储unicode的时候有两种选择,选择unicode big endian则通过conv("GB2312","UTF-16"...)即可,另外一种不行。
iconv判断字节序是"with machine dependent endianness and alignment"

故我写了一个iconv的扩展来解决这个问题:
class Iconv
  def Iconv.conv_from_unicode_gb2312(str,big_endian=true)
    unless big_endian
      odd_or_even = 1
      i = 0
      str.each_byte{|c|
        odd_or_even = 1 - odd_or_even
        if odd_or_even==0
          str[i],str[i+1] = str[i+1],str[i] if str[i]>0
          i += 2
        end
      }
    end
    Iconv.iconv("GB2312","UTF-16",str)
  end
end

通过这个方法将字节序调换一下再进行转换
0 请登录后投票
   发表时间:2006-09-25  
albert_qhd 写道
搞清楚了,是涉及unicode的big-endian及little-endian的问题
notepad存储unicode的时候有两种选择,选择unicode big endian则通过conv("GB2312","UTF-16"...)即可,另外一种不行。


x86平台上utf16和utf-16le应该是一样的,按你前面说的“汉”字的2个字节是73, 108,这本身就是utf-16le编码的,在x86平台上直接用utf16解码就可以了。

如果你的测试总是在这2种编码之间游离,除了把自己绕晕以外没什么别的好处。
albert_qhd 写道

iconv判断字节序是"with machine dependent endianness and alignment"

故我写了一个iconv的扩展来解决这个问题:
。。。。。引用省略
通过这个方法将字节序调换一下再进行转换

不用这么麻烦,iconv在转换时会根据前面的2字节BOM进行判断,如果你不去掉这2字节,它自己就能正确判断出LE或BE了。即便是没有这2个字节,也可能通过utf-16le或utf-16be这2个编码进行转换。
1 请登录后投票
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics