首页 > 代码库 > Win32API UNICODE编码&宽字节

Win32API UNICODE编码&宽字节

Win32API UNICODE编码&宽字节

    • 计算机是由于是美国人发明的,所以字符集先以英文为主。上世纪三十年代,满足自己的编码方式:ASC编码方式,以7位(bit)代表一个字符,能表示的字符才128个。因为以前内存很贵。128个字符足够美国人用的了。
    • 计算机发展到欧洲,发现ASC是不够用的。就发展为ASCII
      • 欧洲有些国家是不用英文的:如西班牙等~~
        • 升级ASCII后,用8位内存来表示字符编码,有256个字符。如此前128个定下来永久不变,后面128个分配给欧洲其它语种。欧洲有十几个国家,发现还是不够用。美国人采取了一种折中办法:在不增加内存的情况下,采取(CodePage)“代码页”的机制来表示字符编码。用一个数字来表示一个语种:比如用936代码汉语,或是用437代码英语等。如果代码页是中文代码页,后128就是汉字。如果代码页437那么后128就是英文。
    • 记住ASCII的常用3个位置:
      • 1 小写a的ASCII编码:97 ##助记:(眼镜a),香港回归
      • 2 大写A的ASCII编码:65
      • 3 阿拉伯数字0的ASCII编码:48 ##助记:盗圣,你的事发(48)~~”&&香港回归,建国48年(97-49
    • 又过了些年发展,计算机来到亚洲,(8bit) 256也是不够用的。
      • 就是说汉字,后128给我们是绝对不够用的。就发展成DBCS(单双字节混合编码6万多个字符),当前计算机的主流编码方式。
      • DBCS这种编码先天具有缺陷,先天“小儿麻痹”,一个处理不当会产生乱码。因为英文占一个字节,汉字占两个字节,这个规定就不是唯一的,容易出错。解析字符串的时候,要有两种标准来分析字符串,处理就会先天的慢一些。
      • 最后就出现了UNICODE编码方式:可以认为是DBCS上的一个补丁,UNICODE统一规范:所有字符全部2个字符编码,英文汉字全部一发切,能能按两个字节来编码。在英文高字节上补0.
    • UNICODE编码方式有个缺点:占用内存空间,有浪费的嫌疑,但以现在的硬件来看,已经不是问题了。但它并不是市场上主流的编码方式。
    • 字符集的应用
      • char 有占用1个字节,有占用两个字节 (DBCS编码)
      • 宽字节 wchar_t每个占用两个字节 (UNICODE编码)
        • wchar_t实际是unsigned short类型(占用2个字节)
        • 定义时需要增加“L”. 给编译器看,通知编译器按照双字节编译字符串。
        • 需要使用支持wchar_t类型的函数,来操作宽字节字符串。
          wchar_t* pwszText = L"Hello wchar";
          wprintf(L"%s \n",pwszText);?
        • 这里不能套用标准C中的char*的函数了,双字节的操作一定要采用双字节对应的函数来操作。
    • windows中的新类型: TCHAR
      #ifdef UNICODE
      typedef wchar_t ?
      • 注意定义宏的位置,#ifdef XXX 具有向上朔源的属性,如果代码中有多个ifdef XXX 就应该让它统一的找到定义,或者找不到定义,不能自相矛盾。
        示范代码 定义宏的位置(#define UNICODE)要在windows.h文件的前面定义,因为windows.h头文件包含有WINNT.H文件,WINNT.H里面有“#ifdef UNICODE”的判断检测。

        #define UNICODE
        #include "stdafx.h"
        #include "stdio.h"
        #include <tchar.h>
        #include <windows.h>

        void T_char()
        {
        TCHAR *pszText = _TEXT("Hello");
        #ifdef UNICODE
        wprintf(L"%s\n",pszText);
        #else
        printf("单:%s\n",pszText);
        #endif

        }

        int main()
        {
        T_char();
        return 0;
        }
    • 示例: UNICODE编码中wprintf函数的支持有限,不完善,需要更换
      // WinChar.cpp : Defines the entry point for the console application.
      //

      #define UNICODE
      #include "stdafx.h"
      #include "stdio.h"
      #include <tchar.h>
      #include <windows.h>

      void PrintUnicode()
      {
      for (WORD nHigh = 0; nHigh <256; nHigh++)
      {
      for (WORD nLow = 0; nLow<256; nLow++)
      {
      wchar_t wChar = nHigh * 256 +nLow;
      wprintf(L"%s",&wChar);
      }
      printf("\n");
      }
      }

      int main()
      {
      PrintUnicode();
      return 0;
      }
    • UNICODE打印输出要使用 WriteConsole这个API来实施。
      BOOL WriteConsole(
      ?IN HANDLE hConsoleOutput, //标准输出句柄
      ?IN CONST VOID *lpBuffer, //输出内容的Buffer缓冲
      ?IN DWORD nNumberOfCharsToWrite, //准备输出内容长度
      ?OUT LPDWORD lpNumberOfCharsWritten, //返回实际输出内容长度
      ?IN LPVOID lpReserved //备用
      ? );
      • 只有三个特殊的指向设备的句柄:1 键盘 2 显示器 3 错误设备 (其它句柄均指向内存)
        HANDLE WINAPI GetStdHandle(
        _In_ DWORD nStdHandle //input,output, or error device
        );//返回值 获取相应的标准句柄

Win32API UNICODE编码&宽字节