最近一直在研究Unicode编程,有一些体验,不过还是有点处于混沌状态的感觉。
MSDN里面有几段文字讲Unicode流I/O操作函数访问的。里面讲到如果以文本模式打开文件,那么Unicode流I/O函数在读写文件时会进行两种类型的字符转换:(1)Unicode与MBCS互转;(2)CR-LF组合与单个换行字符间的转换。
Unicode与MBCS转换发生在读写文件时,读的时候Unicode流I/O函数假定流文件为多字节字符序列,将读进来的字符转换成宽字符,写的时候将宽字符转换成多字节字符。
CR-LF组合与单个换行字符间的转换发生在读之前和写之后。
但是如果流文件指定以二进制模式打开,那么Unicode流I/O函数则认为文件是Unicode编码格式的,因此读写时不会做上述转换。
看完这些文字,我用之前写的控制台程序做了个实验,明白了一些东西,但仍然有些东西不明白。
在控制台程序中我用fgetwc 从stdin读字符,默认情况下stdin也是以文本模式打开的,所以fgetwc 会假定输入是多字节字符序列,所以一个汉字是两个字节,那么fgetwc 读的时候会将每个字节都转换成Unicode宽字符,这样其实一个汉字就占了4个字节。
如果想一次性读入一个汉字的Unicode码,必须调用_setmode( _fileno( stdin ), _O_BINARY ); 修改stdin的打开模式。我试了一下,fgetwc 可以一次读入两个字节。而且一个Enter键对应的值是0x0a0d,0x0a是换行,0x0d是回车。如果对标准输出也调用setmode 设置为二进制模式,那么读的内容是可以打印在控制台上的。
不过还有一个问题没弄明白,就是同一个汉字,比如“我”字,从控制台输入的Unicode值为53966,也就是0xd2ce,但是如果我在程序中定义一 个字符串“我”,那么它的值是25105,也就是0x6211。可能控制台使用的代码页编号为936(简体中文GBK),此字符集中我的码值可能就是 53966,而程序内部使用的是Unicode编码,所以导致二者不一致。但是不知道Unicode UTF-16编码的代码页编号是多少,查控制面板中的代码页转换表中好像没有。
MSDN里面有几段文字讲Unicode流I/O操作函数访问的。里面讲到如果以文本模式打开文件,那么Unicode流I/O函数在读写文件时会进行两种类型的字符转换:(1)Unicode与MBCS互转;(2)CR-LF组合与单个换行字符间的转换。
Unicode与MBCS转换发生在读写文件时,读的时候Unicode流I/O函数假定流文件为多字节字符序列,将读进来的字符转换成宽字符,写的时候将宽字符转换成多字节字符。
CR-LF组合与单个换行字符间的转换发生在读之前和写之后。
但是如果流文件指定以二进制模式打开,那么Unicode流I/O函数则认为文件是Unicode编码格式的,因此读写时不会做上述转换。
看完这些文字,我用之前写的控制台程序做了个实验,明白了一些东西,但仍然有些东西不明白。
在控制台程序中我用fgetwc 从stdin读字符,默认情况下stdin也是以文本模式打开的,所以fgetwc 会假定输入是多字节字符序列,所以一个汉字是两个字节,那么fgetwc 读的时候会将每个字节都转换成Unicode宽字符,这样其实一个汉字就占了4个字节。
如果想一次性读入一个汉字的Unicode码,必须调用_setmode( _fileno( stdin ), _O_BINARY ); 修改stdin的打开模式。我试了一下,fgetwc 可以一次读入两个字节。而且一个Enter键对应的值是0x0a0d,0x0a是换行,0x0d是回车。如果对标准输出也调用setmode 设置为二进制模式,那么读的内容是可以打印在控制台上的。
不过还有一个问题没弄明白,就是同一个汉字,比如“我”字,从控制台输入的Unicode值为53966,也就是0xd2ce,但是如果我在程序中定义一 个字符串“我”,那么它的值是25105,也就是0x6211。可能控制台使用的代码页编号为936(简体中文GBK),此字符集中我的码值可能就是 53966,而程序内部使用的是Unicode编码,所以导致二者不一致。但是不知道Unicode UTF-16编码的代码页编号是多少,查控制面板中的代码页转换表中好像没有。