Unicode与ANSI(转载)

一、Unicode与ANSI简介
    1.Unicode与ANSI两种字符编码方式,就是说我们平常所定的字,在计算机中是怎么存储的。美国人所用的英语总共用到26个字符再加0-9,再加上其它一些标点,也不过就128个。而计算机中的一个字节就有8位,共有256种组合(每一位有两种可能(0或1)、一共有8位。结果就是8个2连乘)。所以说对美国人来将所有字符一个字节就够了(计算机是他们发明的,当时当然也没有想外国也要用);好的,一人字节表示英语到还够了,可是我们的汉字,韩国的韩文呢!后来,几个大公司联合起来起草了用2个字节来表示字符的Unicode,2字节有65535种组合,所以对全球的字符都够。
二、Windows对Unicode的支持
     1、Win98仅支持ANSI
     2、WinCE仅支持Unicode
     3、Win2000支持Unicode,兼容ANSI,也就是所说所有核心程序都是在Unicode下运行的,如果你调用ANSI版本的API,它就所你的内容翻译成Unicode,然后计算,然后将计算结果再转换成ANSI传给你。
三、Unicode与ANSI之间的转换

#include "stdafx.h"
#include <windows.h>
#include <lm.h>
#include <stdio.h>

int _tmain(int argc, _TCHAR* argv[])
{
 PSTR pStr = {"这量一个ANSI的字串"},pNew;
 
 PWSTR pWideCharStr;
 int nLen;
 BOOL fOk = FALSE;

 //计算ANSI转换成Unicode后需要的字符数
 //其中pStr为ANSI字符串
 nLen = MultiByteToWideChar(CP_ACP, 0, pStr, -1, NULL, 0);
 //分配存放Unicode字串的内存
 pWideCharStr = new WCHAR( nLen * sizeof(WCHAR));
 printf("%d",strlen(pStr));  //18个字符
 //进行转换ANSI---->Unicode;其中nLen指明存放Unicode的内存大小
 MultiByteToWideChar(CP_ACP, 0, pStr, -1, pWideCharStr, nLen);
 //以下是Unicode--->ANSI;其中strlen(...)表示存放ANSI的内存大小
 pNew= new char(15);
 WideCharToMultiByte(CP_ACP, 0, pWideCharStr, -1, pNew, strlen(pNew), NULL, NULL);
 //当分配的内存过小时,会出现字符串截取
 
 //int WideCharToMultiByte(
 //UINT CodePage,            // code page
 //DWORD dwFlags,            // performance and mapping flags
 //LPCWSTR lpWideCharStr,    // wide-character string
 //int cchWideChar,          // number of chars in string.
 //LPSTR lpMultiByteStr,     // buffer for new string
 //int cbMultiByte,          // size of buffer
 //LPCSTR lpDefaultChar,     // default for unmappable chars
 //LPBOOL lpUsedDefaultChar  // set when default char used
 //);
 //int MultiByteToWideChar(
 //  UINT CodePage,         // code page
 //  DWORD dwFlags,         // character-type options
 //  LPCSTR lpMultiByteStr, // string to map
 //  int cbMultiByte,       // number of bytes in string
 //  LPWSTR lpWideCharStr,  // wide-character buffer
 //  int cchWideChar        // size of buffer
 //);
 //当成功返回时,并且参数cchWideChar值为非0时,返回值为写到lpWideCharStr所指的缓冲中的数量
 //当成功返回时,并且参数cchWideChar值为0时,返回的值为所要存放的字符数。
 //当dwFlag = 0,输入的字符串是UTF-8并包含无效字符时,返回 ERROR_NO_UNICODE_TRANSLATION.
 //当函数失败时,返回0,GetLastError如下:
 //ERROR_INSUFFICIENT_BUFFER
 //ERROR_INVALID_FLAGS
 //ERROR_INVALID_PARAMETER
 //ERROR_NO_UNICODE_TRANSLATION
 //汉字占两个字节,全角字符占两个字节,半角占一个字节。
 return 0;
}
四、成为符合ANSI和Unicode的应用程序[此段摘自Windows核心编程]

即使你不打算立即使用Unicode ,最好也应该着手将你的应用程序转换成符合Unicode 的应用程序。下面是应该遵循的一些基本原则:

• 将文本串视为字符数组,而不是chars数组或字节数组。
• 将通用数据类型(如TCHAR和PTSTR)用于文本字符和字符串。
• 将显式数据类型(如BYTE和PBYTE)用于字节、字节指针和数据缓存。
• 将TEXT宏用于原义字符和字符串。
• 执行全局性替换(例如用PTSTR替换PSTR)。
• 修改字符串运算问题。例如函数通常希望你在字符中传递一个缓存的大小,而不是字节。

这意味着你不应该传递sizeof(szBuffer) ,而应该传递(sizeof(szBuffer) / sizeof( TCHAR)。另外,如果需要为字符串分配一个内存块,并且拥有该字符串中的字符数目,那么请记住要按字节来分配内存。这就是说,应该调用malloc(nCharacters *sizeof(TCHAR)),而不是调用malloc(nCharacters)。在上面所说的所有原则中,这是最难记住的一条原则,如果操作错误,编译器将不发出任何警告。

当我为本书的第一版编写示例程序时,我编写的原始程序只能编译为ANSI程序。后来,当我开始撰写本章的内容时,我想我应该鼓励使用Unicode ,并且打算创建一些示例程序,以便展示你可以非常容易地编写既可以用Unicode 也可以用ANSI来编译的程序。这时我发现最好的办法是将本书的所有示例程序进行转换,使它们都能够用Unicode 和ANSI进行编译。

五、其它
    _UNICODE,_TEXT宏都是c运行库中定义的宏。
   UNICODE,TEXT宏是在Windows.h/Winnt.h中定义的。所以当要调用WindowAPI时。如果要编译UNICODE版程序时,要定义UNICODE宏,如果还用到C运行库中对UNICODE的支持时,就应还定义一个_UNICODE宏。也就是说通常都要定义两个宏UNICODE和_UNICODE。
//摘自<windows 核心编程>
char szA[100];             //An ANSI string buffer
WCHAR szW[100];            //A Unicode string buffer

//Normal sprintf:all strings are ANSI
sprintf(szA, "%s","ANSI Str");

//Converts Unicode string to ANSI
sprintf(szA,"%S",L"Unicode Str");

//Normal swprintf:all strings are Unicode
swprintf(szW,L"%s",L"Unicode Str");

//Converts ANSI string to Unicode
swprintf(szW,L"%S", "ANSI Str");
感觉printf不能实现对数据编码的通用化。
//要么print ANSI  
_tprintf(_T("小s %s   "), str);
//要么print UNICODE
_tprintf(_T("大S %S "), str);

------------------------------------------------------------------------------
写一篇,结果没有保存到csdn blog上去,又重写,真把我气得够呛!下次吸取教训千万不要在线写文章了,真不安全!

posted @ 2011-09-20 00:13  冒牌工程师  阅读(1997)  评论(0编辑  收藏  举报