1. 程式人生 > >Win32API UNICODE編碼&寬字節

Win32API UNICODE編碼&寬字節

定義 自己 市場 計算機 數字 try type 文件 code

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編碼&寬字節