• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            醬壇子

            專注C++技術(shù) 在這里寫下自己的學(xué)習(xí)心得 感悟 和大家討論 共同進(jìn)步(歡迎批評(píng)!!!)

              C++博客 :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
              66 Posts :: 16 Stories :: 236 Comments :: 0 Trackbacks

            公告

            王一偉 湖南商學(xué)院畢業(yè) 電子信息工程專業(yè)

            常用鏈接

            留言簿(19)

            我參與的團(tuán)隊(duì)

            搜索

            •  

            積分與排名

            • 積分 - 387045
            • 排名 - 64

            最新隨筆

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            UNICODE
            作者:NorthTibet


            簡(jiǎn)介

            ????如果你編寫的程序是針對(duì)非英語(yǔ)國(guó)家的用戶,如中國(guó)、日本、東歐和中東地區(qū),那么你一定要熟悉 UNICODE 字符集。尤其是用 Visual C++/MFC 編寫針對(duì)上述國(guó)家和地區(qū)的用戶的程序時(shí),如果你想讓自己的應(yīng)用程序得到更廣泛的用戶,那么必須考慮代碼 UNICODE 的兼容性,也就是說它既在 ASCII 模式下運(yùn)行 ,也能在UNICODE 模式下運(yùn)行。本文將介紹 UNICODE 的一些基本編程知識(shí),澄清很多人(包括我自己)在這個(gè)問題上存在的模糊認(rèn)識(shí)。對(duì)于任何使用 Visual C++ 和/或 MFC 編程的人來說,這篇文章肯定值得一讀。

            UNICODE到底是什么?

            ????UNICODE 是目前用來解決 ASCII 碼 256 個(gè)字符限制問題的一種比較流行的解決方案。大家知道,ASCII 字符集只有256個(gè)字符,用 0-255 之間的數(shù)字來表示。包括大小寫字母、數(shù)字以及少數(shù)特殊字符;如標(biāo)點(diǎn)符號(hào)、貨幣符號(hào)等。對(duì)于大多數(shù)拉丁語(yǔ)言來說,這些字符已經(jīng)夠用。但是,許多亞洲和東方語(yǔ)言所用的字符遠(yuǎn)遠(yuǎn)不止256個(gè)字符。有些超過千個(gè)。人們?yōu)榱送黄?ASCII 碼字符數(shù)的限制,試圖用一種簡(jiǎn)單的方法來針對(duì)超過256個(gè)字符的語(yǔ)言編寫計(jì)算機(jī)程序。于是 UNICODE 應(yīng)運(yùn)而生。UNICODE 通過用雙字節(jié)來表示一個(gè)字符,從而在更大范圍內(nèi)將數(shù)字代碼映射到多種語(yǔ)言的字符集。

            Visual C++的解決方案

            ??? 作為軟件開發(fā)人員,如何熟練有效地使用 UNICODE 呢?如果你正在用 Visual C++ 編寫程序,UNICODE 兼容性意味著你的程序是否具有國(guó)際化特征,也就是說你的應(yīng)用程序是針對(duì)本地市場(chǎng)還是國(guó)際市場(chǎng)。一旦你作出了決定,那么就得在代碼中實(shí)現(xiàn)具體細(xì)節(jié)。好在 Visual C++ 提供了很多內(nèi)建功能來支持 UNICODE,在創(chuàng)建工程時(shí)就可以利用 Visual C++ 提供的這些功能。在產(chǎn)生應(yīng)用程序框架代碼之前,AppWizard 允許開發(fā)人員決定是否支持 UNICODE。Win32 SDK 包含有一些數(shù)據(jù)類型遵循 UNICODE 編碼規(guī)則,MFC 以宏的形式提供了將一般文本轉(zhuǎn)換成 UNICODE 數(shù)據(jù)類型的途徑。開發(fā)人員只需要稍微改變一下編寫代碼的習(xí)慣便可以輕松編寫支持 UNICODE 的應(yīng)用。

            字符串

            ??? C 程序員一般是用 char 關(guān)鍵字象下面這樣來聲明一個(gè)字符串?dāng)?shù)組:
                   char str[100];       
            象下面這樣聲明函數(shù)原形:
                   void strcpy( char *out, char *in );        


            為了將上面的聲明改成支持雙字節(jié)的 UNICODE 字符集,可以用下面的方法:

                   wchar_t str[100];        
            或者
                   void wcscpy( wchar_t *out, wchar_t *in );        

            ??? 此外,微軟還提供一種通過預(yù)處理指令來實(shí)現(xiàn) UNICODE。每當(dāng)用 Visual C++ 創(chuàng)建新工程時(shí),只要確定是否支持另外一種字符集,則 AppWizard 將會(huì)在頭文件中插入預(yù)處理指令。這些指令告訴編譯器程序想要支持何種字符集。這樣在使用VC++提供的通用數(shù)據(jù)類型時(shí),編譯器將用相應(yīng)的數(shù)據(jù)類型把通用數(shù)據(jù)類型替換成所需要支持的字符集。這樣很容易將代碼重新編譯成支持其它字符集的程序。
            ??? 為了在 Visual C++ 6.0 中激活 UNICODE 標(biāo)準(zhǔn),可以這樣做:打開工程文件后,從主菜單中選擇“Project | Settings”打開工程設(shè)置對(duì)話框 => 然后選擇“C/C++”標(biāo)簽 => 在“Preprocessor definitions”編輯框中添加 UNICODE 或者 _UNICODE 預(yù)處理宏指令。如圖一所示:


            圖一 Project Settings 對(duì)話框

            注意這里的 UNICODE 和 _UNICODE 有什么區(qū)別呢?前者沒有下劃線,專門用于 Windows 頭文件;后者有一個(gè)前綴下劃線,專門用于 C 運(yùn)行時(shí)頭文件。
            在代碼中,凡是用關(guān)鍵字 char ?的地方都用 TCHAR 取代;凡是用 char * 的地方都用 LPTSTR 取代;凡是定義在雙引號(hào)中的字符串常量(如"VCKBASE Online Journal")都用 TEXT 宏重寫:

                   TEXT("VCKBASE Online Journal");       
            TEXT 宏的主要作用是當(dāng)定義了 UNICODE/_UNICODE 預(yù)處理指令時(shí),字符串被標(biāo)志為雙字節(jié)字符串,否則字符串被標(biāo)示為 ANSI 字符串。TEXT 的定義如下:
                  TEXT(
                       LPTSTR string // ANSI 或者 Unicode 字符串
                  );
                  參數(shù)   string 為字符串指針,指向被解釋的 Unicode 或者 ANSI 字符串
            在文檔中 微軟提供了包括通用類型在內(nèi)的幾種數(shù)據(jù)類型都與 ASCII 和 UNICODE兼容。這一點(diǎn)可以參考微軟在線文檔有關(guān)“通用數(shù)據(jù)類型和數(shù)據(jù)類型”的章節(jié)。

            例子代碼

            下面通過一些簡(jiǎn)單的例子來進(jìn)一步探討 UNICODE 編程。

            使用 ASCII 字符集的“Hello, World”:

            //*********************************
            // 用 MFC 實(shí)現(xiàn)的"Hello World!" 代碼
            //*********************************

            //hello.cpp
            
            #include <afxwin.h>
            
            // Declare the application class
            class CHelloApp : public CWinApp
            {
            public:
               virtual BOOL InitInstance();
            };
            
            // Create an instance of the application class
            CHelloApp HelloApp;
             
            // Declare the main window class
            class CHelloWindow : public CFrameWnd
            {
               CStatic* cs;
            public:
               CHelloWindow();
            };
            
            // The InitInstance function is called each
            // time the application first executes.
            BOOL CHelloApp::InitInstance()
            {
               m_pMainWnd = new CHelloWindow();
               m_pMainWnd->ShowWindow(m_nCmdShow);
               m_pMainWnd->UpdateWindow();
               return TRUE;
            }
            
            // The constructor for the window class
            CHelloWindow::CHelloWindow()
            {
               // Create the window itself
               Create(NULL, "Hello World!", WS_OVERLAPPEDWINDOW, 
                      CRect(0,0,200,200)); 
            	
               // Create a static label
               cs = new CStatic();
               cs->Create("hello world", WS_CHILD|WS_VISIBLE|SS_CENTER, 
                          CRect(50,80,150,150), this);
            }
            

            修改上面的代碼使之支持 UNICODE 字符集,串常量必須要改成對(duì)應(yīng)的 UNICODE 字符。方法是對(duì)串常量使用TEXT 宏。這個(gè)宏將告訴預(yù)處理器檢查使用什么樣的字符標(biāo)準(zhǔn):

            // The constructor for the window class
            CHelloWindow::CHelloWindow()
            {
               // Create the window itself
               Create(NULL, TEXT("Hello World!"), WS_OVERLAPPEDWINDOW, 
                      CRect(0,0,200,200));
            	
               // Create a static label
               cs = new CStatic();
               cs->Create( TEXT("hello world!"), WS_CHILD|WS_VISIBLE|SS_CENTER, 
                          CRect(50,80,150,150), this);
            }

            當(dāng)預(yù)處理器碰到通用數(shù)據(jù)類型,它便檢查 AFXWIN.H 頭文件的 _UNICODE 定義。然后根據(jù) UNICODE 定義插入相應(yīng)的的數(shù)據(jù)類型。

            下面的這個(gè)例子使用 Win32 API 函數(shù)和通用數(shù)據(jù)類型設(shè)置 C 盤的卷標(biāo)。

            //******************
            // 設(shè)置 C 盤的卷標(biāo)
            //******************

            // drvsvl.cpp
            
            #include <windows.h>
            #include <iostream.h>
            
            void main()
            {
               BOOL success;
               char volumeName[MAX_PATH];
            
               cout << "輸入新的 C 盤卷標(biāo):";
               cin >> volumeName;
            
               success = SetVolumeLabel("c:\\", volumeName);
               if (success)
                  cout << "成功\n";
               else
                  cout << "錯(cuò)誤代碼:" << GetLastError() << endl;
            }

            通過使用 TCHAR 數(shù)據(jù)類型,將這段代碼最上面的字符數(shù)組聲明為兩個(gè)字節(jié)的字符。TEXT 宏再次被用于字符串常量:

            void main()
            {
               BOOL success;
            	
               TCHAR volumeName[MAX_PATH];
            
               cout << TEXT("輸入新的 C 盤卷標(biāo): ");
               cin >> volumeName;
            
               success = SetVolumeLabel(TEXT("c:\\" ), volumeName);
               if (success)
                  cout << TEXT("成功\n");
               else
                  cout << TEXT("錯(cuò)誤代碼:") << GetLastError() << endl;
            } 
            Visual C++ 中的通用數(shù)據(jù)類型

            ??? Visual C++ 提供了幾種 MFC 專用的數(shù)據(jù)類型用于創(chuàng)建具有國(guó)際化特性的應(yīng)用程序。這些定義很通用,完全可以在 UNICODE、ASCII、DBCS (雙字節(jié)字符集) 和 MBCS (多字節(jié)字符集)。由于篇幅所限,本文不打算涉及所有上面提到的這些字符集。有關(guān)它們的詳細(xì)資料請(qǐng)參考相關(guān)資料。MFC 提供了一種透明的方式來實(shí)現(xiàn)這些字符集。通用數(shù)據(jù)類型的映射到哪個(gè)字符集以及映射方式是根據(jù)工程的設(shè)置決定的,默認(rèn)值為 ASCII 模式,其它幾個(gè)可選項(xiàng)是 MBCS、DBCS 或者 UNICODE。本文主要討論 UNICODE,所以下表中只列出了 ASCII 與 UNICODE 字符之間的映射關(guān)系:

            表一:

            通用 MFC 數(shù)據(jù)類型
            映射到 ASCII
            映射到 UNICODE
            注釋
            _TCHAR
            char
            wchar_t
            _TCHAR 是一個(gè)映射宏,當(dāng)定義 UNICODE 時(shí),該數(shù)據(jù)類型映射到 wchar_t,如果沒有定義 UNICODE,那么它映射到 char。
            _T 或 _TEXT
            char 常量字符串
            wchar_t 常量字符串
            功能與宏相同,在 ASCII 模式下,它們被忽略,也就是說被預(yù)處理器刪除掉,但是如果定義了UNICODE, 則它們會(huì)將常量字符串轉(zhuǎn)換成等價(jià)的 UNICODE 。
            LPTSTR
            char*, LPSTR(Win32)
            wchar_t*
            可移植的32位字符串指針。它將字符類型映射到工程設(shè)置的類型。
            LPCTSTR
            const char*, LPCSTR(Win32)
            const wchar_t*
            可移植的32位常量字符串指針。它將字符類型常量映射到工程設(shè)置的類型。

            使用表一中列出的通用數(shù)據(jù)類型,開發(fā)人員可以保證所創(chuàng)建的工程始終是針對(duì)一種字符集,這些通用數(shù)據(jù)類型就相當(dāng)于占位符,在編譯時(shí)被特定的字節(jié)所替代,使得應(yīng)用程序在 ASCII 和 UNICODE 模式下都能運(yùn)行。但是,有一點(diǎn)要特別注意,那就是上述的通用數(shù)據(jù)類型為微軟專有,與 ANSI 標(biāo)準(zhǔn)并不兼容。有關(guān)微軟提供的這些通用數(shù)據(jù)類型詳細(xì)描述請(qǐng)參考 MSDN 庫(kù)文檔。

            有關(guān)技術(shù)注釋

            ??? 為了成功編譯支持 UNICODE 的 MFC 程序,必須使用 MFC 的 UNICODE 版本庫(kù)。該庫(kù)在定制安裝Visual C++ 時(shí)是個(gè)可選安裝項(xiàng)。
            ??? 有一點(diǎn)很重要:那就是不使用 UNICODE 標(biāo)準(zhǔn)在外觀上并不影響程序的執(zhí)行。也就是說,上面提到過的代碼不管設(shè)沒設(shè)置 _UNICODE 生成選項(xiàng),最終都能生成正常運(yùn)行的程序。當(dāng)開發(fā)人員使用多個(gè)版本的Win32 API函數(shù)時(shí)才會(huì)出現(xiàn)問題。
            ??? 在使用多個(gè)版本的 Win32 API函數(shù)(任何有字符或字符串作為參數(shù)的 Win32 API函數(shù))時(shí),編譯器根據(jù)是否設(shè)置 _UNICODE 指令來決定調(diào)用正確的函數(shù)。如果沒有定義_UNICODE,那么編譯器將默認(rèn)調(diào)用 ASCII 版本函數(shù)。

            結(jié)束語(yǔ)

            ??? 綜上所述可以看到,編譯 UNICODE 版本的程序并不難。只是在編寫代碼時(shí)記住函數(shù)調(diào)用上些微的變化。微軟為此提供的擴(kuò)展是開發(fā)人員能夠以透明的方式選擇所用的字符集,為應(yīng)用軟件的國(guó)際化打開了方便之門。
            ??? Jeffrey Richter 在他的《Windows 核心編程》(機(jī)械工業(yè)出版社-王建華、張煥生、侯麗坤等譯)一書中專門用一章討論了 UNICODE。翻譯得也不錯(cuò)。有興趣的朋友不妨找來看看。

            posted on 2007-01-05 13:18 @王一偉 閱讀(4108) 評(píng)論(4)  編輯 收藏 引用

            Feedback

            # re: UNICODE 介紹 2007-01-09 13:33 eXile
            這兩行是錯(cuò)誤的:
             cout << TEXT("輸入新的 C 盤卷標(biāo): ");
            cin >> volumeName;
            cin, cout并不能處理UNICODE,按照Microsoft的風(fēng)格,可能也要定義一個(gè)tin, tout...

            要支持UNICODE,各式各樣的字符串處理才是困難的地方。
              回復(fù)  更多評(píng)論
              

            # re: UNICODE 介紹 2007-11-28 23:07 82860801
            看完之后有點(diǎn)明白了大體意思!  回復(fù)  更多評(píng)論
              

            # re: UNICODE 介紹 2007-12-29 16:32 Solomon Joh
            可以講講UNIX/LINUX下的unicode編程知識(shí)嗎?  回復(fù)  更多評(píng)論
              

            # re: UNICODE 介紹 2007-12-30 08:06 @王一偉
            沒有涉及過unix/linux編程哦 可以探討下 過陣我會(huì)研究一下linux下的,d等我有兩臺(tái)電腦的時(shí)候 呵呵
              回復(fù)  更多評(píng)論
              


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            亚洲精品99久久久久中文字幕 | 成人久久精品一区二区三区| 久久精品国产亚洲AV大全| 国产精品视频久久| 久久婷婷色综合一区二区| 99久久精品午夜一区二区| 人妻无码久久精品| 久久电影网一区| 伊人久久久AV老熟妇色| 国产精品嫩草影院久久| 久久久久女人精品毛片| 色狠狠久久综合网| 91久久九九无码成人网站| 亚洲国产精品无码久久98| 欧美色综合久久久久久| 久久亚洲国产午夜精品理论片| 伊人久久大香线蕉AV色婷婷色| 久久久久亚洲AV成人网| 99久久精品午夜一区二区| 久久亚洲中文字幕精品一区| 久久久99精品成人片中文字幕 | 国产精品久久久久影院色| 无码8090精品久久一区| 26uuu久久五月天| 久久精品国产99国产精偷 | 久久久久亚洲精品天堂久久久久久 | 99久久精品免费国产大片| 精品久久久久久亚洲精品| 久久人人爽人人爽人人片AV高清| 中文字幕亚洲综合久久| 精品久久久久久综合日本| 少妇内射兰兰久久| 亚洲精品乱码久久久久久蜜桃不卡| 亚洲国产高清精品线久久| 日韩精品无码久久一区二区三| 久久精品国产99国产精品| 99久久久久| 久久午夜综合久久| 一本一道久久a久久精品综合 | 久久亚洲精品成人无码网站| 久久久久99这里有精品10|