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上去,又重写,真把我气得够呛!下次吸取教训千万不要在线写文章了,真不安全!