今天发现 QQWry 升级程序的一些按钮和对话框中文显示乱码,但是在全新建立的 Wine prefix 中正常。经与新 prefix 的比对,将以下注册表信息写入system.reg
后即恢复正常:
[System\\CurrentControlSet\\Control\\FontAssoc\\Associated Charset] "ANSI(00)"="YES" "OEM(FF)"="YES" "SYMBOL(02)"="NO"
今天发现 QQWry 升级程序的一些按钮和对话框中文显示乱码,但是在全新建立的 Wine prefix 中正常。经与新 prefix 的比对,将以下注册表信息写入system.reg
后即恢复正常:
[System\\CurrentControlSet\\Control\\FontAssoc\\Associated Charset] "ANSI(00)"="YES" "OEM(FF)"="YES" "SYMBOL(02)"="NO"
用于显示时,经常会遇到显示的文本太长需要截短的情况。如果是如 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
今天同学向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 文档的支持。