9
16
2013
4

记一次 Wine 乱码

今天发现 QQWry 升级程序的一些按钮和对话框中文显示乱码,但是在全新建立的 Wine prefix 中正常。经与新 prefix 的比对,将以下注册表信息写入system.reg后即恢复正常:

[System\\CurrentControlSet\\Control\\FontAssoc\\Associated Charset]
"ANSI(00)"="YES"
"OEM(FF)"="YES"
"SYMBOL(02)"="NO"
Category: 中文支持 | Tags: 乱码 wine 中文支持
9
18
2012
12

截短 UTF-8 字符串

用于显示时,经常会遇到显示的文本太长需要截短的情况。如果是如 ASCII 这样的定长编码,截短到指定长度自然不成问题。可如果源字符串是 UTF-8 编码的呢?ANSI C 里只管字节不管编码,所以如果想只用 ANSI C 提供的功能的话,就只能自己写了。因为需求仅仅是截短字符串而已,也不要求多么精确,所以没有去做编解码,只是丢弃按字节截短后的字符串最后的无效编码而已。而且目标语种是 Lua,也不方便搞位操作。

维基百科可知,UTF-8 多字节字符第一字节的最高两位为11,而其它字节的最高两位均为10。所以就把后面那些10xxxxxx连同最开始的11xxxxxx去掉好了。这样会多截掉一个多字节字符,但无所谓了。

function truncateUTF8String(s, n)
  local r = string.sub(s, 1, n)
  local last = string.byte(r, n)
  if not last then return r end
  while last >= 128 and last <= 192 do
    n = n - 1
    r = string.sub(r, 1, n)
    last = string.byte(r, n)
  end
  if last >= 128 then
    r = string.sub(r, 1, n-1)
  end
  return r
end

2012年9月27日更新:感谢Fermat618提供的思路,更新了更简洁、准确的代码如下:

function truncateUTF8String(s, n)
  local dropping = string.byte(s, n+1)
  if not dropping then return s end
  if dropping >= 128 and dropping < 192 then
    return truncateUTF8String(s, n-1)
  end
  return string.sub(s, 1, n)
end
Category: 编程 | Tags: 乱码 Lua 中文支持
3
25
2010
22

Linux 下 zip 文件名乱码解决

今天同学向QQ群邮箱里上传文件用了 zip 格式。于是乱码问题再次摆在了面前。

rar 格式和 7z 格式是我所仅知道的两种支持 UTF-8 格式的压缩文件格式。本来平时大家都喜欢用 rar 格式的,不知道为什么这次得到课件的同学却使用了 zip 格式。以前 zip 是支持指定编码解压的,但不知什么时候升级了后就没有这个选项了。于是尝试使用我曾经写过的gbkunzip这个 Python 脚本来解压,却出错了,说不能用 latin1 解码某个字符。

晕啊!当初只为了一时之需没好好写,当时测试成功了现在却不行了。尝试着改了几下,无果,于是去看zipfile的代码,才知道转码时应该用cp437编码来着。改正后,在为文件更名时另一个错误跳出来:OSError!查了 Python 手册,应该os.rename()不支持对目录更名。

真是麻烦啊。本来我是把文件解压出来再改名来着。现在我有点烦了,决定从源头入手,把zipfile拿来自己修改,把所有的 utf8 都改成了 gb18030,然后解压那个文件,成功!当初写那个脚本时我怎么没想到这样做呢?

不过,这次解压是成功,还不知道以后会不会再出什么问题。以后遇到问题再完善吧。

2013年5月21日更新:添加对加密 zip 文档的支持。


脚本在此。Arch Linux 用户可从 AUR 安装。

Category: Linux | Tags: linux 乱码 zip

| Theme: Aeros 2.0 by TheBuckmaker.com