DBCS 与命令行的关系

2005年9月26日

DBCS 与命令行的关系

以前不知道 DBCS 的时候,只是隐隐约约地感觉着 WPS,哦不,是 UCDOS 和 CCDOS,用着一种双字节表示中文字符的方法。后来自己写 Windows 程序了,才注意到了这个问题。

Windows 里面不仅仅有 DBCS,还有 MBCS。其区别是 MBCS 把 DBCS 和单字节字符集乃至多字节字符集都包括进来了。MBCS 是通过第一个字节识别是否有第二个字节,再由第一和第二两个字节来识别是否有第三个字节等等来处理的。因此有 _mbsinc(p) 和 _mbsdec(start, p) 两个函数来让指针进位与退位。需要注意的是,完整的用法是 p = _mbsinc(p) 和 p = _mbsdec(start, p)。

正因为 DBCS 占用了一定的编码空间,因此对于以可打印的西文字符作为特殊符号,但处理的时候又没有考虑 DBCS 的程序来说,有可能会出问题。比如,在 GBK 编码里面,第二个字节可能是 @,于是如果有程序以 @ 作为特殊字符,又没有考虑到 DBCS,那么打一个第二个字节为 @ 的中文字,再让那个程序去处理,就会出错。

最近,Windows 的命令行编程让我对 DBCS 有了新的认识。以前在 DOS 的时候,情况应该也差不多。我现在来说一说:DBCS 字符里面不会用控制字符来编码,即使是第二个字节也不会这么说。所谓控制字符是指 ASCII 码在 0 ~ 31 的字符。这是因为控制字符实在太重要了,它们的优先级明显高于可打印字符。DBCS 字符在命令行上总是占用两个英文字符的大小。这是因为 DOS 和 Windows 命令行显示的时候,printf 可能会把一个 DBCS 字符当作两个英文字符输出,而全部输出后显示处理程序才会把它转成中文显示。另外是一般 Windows 下的 C 运行库中 printf 是会处理 DBCS 字符的,其表现在行末如果只有一个空格的位置,而要显示一个 DBCS 字符的时候,它会自动换行。

而像 UTF-8 这样的 MBCS 在 Windows 命令行上面明显不能直接使用。因此,最好的方法还是用 DBCS。或者把它转成 DBCS 再显示。但这样一来,Unicode 的万能性就没有了。有一得必有一失。

相信 Linux 的命令行不会保留这样的老的 DOS 传统,即 DBCS 必须占两格这个传统。因此,处理 DBCS 或 MBCS 命令行的光标位置的最佳方法是打印一个就记录一下光标位置的变化。把光标位置的间距做成数组,这样就可以方便安全地在字符间跳来跳去了。

留下您的评论