<Win32 API> 多字节字符与宽字符 WideCharToMultiByte/MultiByteToWideChar

1. ANSI字符与UNICODE字符对比

Windows中ANSI字符和Unicode字符对比:

字符集标识长度示例
ANSIchar1byte'A'
UNICODEwchar_t2byteL'A'


Windows中的字符串用法:

字符集字符串字符串长度字符串比较字符串比较
ANSI "ansistring"strlenstrcmp/strncmpstrcpy
UNICODEL"unicodestring"wcslenwcscmp/_wcsicmp_tcscpy


Visual Studio中切换ANSI和UNICODE:



ANSI: 使用多字节字符集 #define UNICODE 0

UNICODE: 使用UNICODE字符集 #define UNICODE 1

定义有下面:

#ifdef  UNICODE                     // r_winnt

#ifndef _TCHAR_DEFINED
typedef WCHAR TCHAR, *PTCHAR;
typedef WCHAR TBYTE , *PTBYTE ;
#define _TCHAR_DEFINED
#endif /* !_TCHAR_DEFINED */

typedef LPWCH LPTCH, PTCH;
typedef LPCWCH LPCTCH, PCTCH;
typedef LPWSTR PTSTR, LPTSTR;
typedef LPCWSTR PCTSTR, LPCTSTR;
typedef LPUWSTR PUTSTR, LPUTSTR;
typedef LPCUWSTR PCUTSTR, LPCUTSTR;
typedef LPWSTR LP;
typedef PZZWSTR PZZTSTR;
typedef PCZZWSTR PCZZTSTR;
typedef PUZZWSTR PUZZTSTR;
typedef PCUZZWSTR PCUZZTSTR;
typedef PNZWCH PNZTCH;
typedef PCNZWCH PCNZTCH;
typedef PUNZWCH PUNZTCH;
typedef PCUNZWCH PCUNZTCH;
#define __TEXT(quote) L##quote      // r_winnt

#else   /* UNICODE */               // r_winnt

#ifndef _TCHAR_DEFINED
typedef char TCHAR, *PTCHAR;
typedef unsigned char TBYTE , *PTBYTE ;
#define _TCHAR_DEFINED
#endif /* !_TCHAR_DEFINED */

typedef LPCH LPTCH, PTCH;
typedef LPCCH LPCTCH, PCTCH;
typedef LPSTR PTSTR, LPTSTR, PUTSTR, LPUTSTR;
typedef LPCSTR PCTSTR, LPCTSTR, PCUTSTR, LPCUTSTR;
typedef PZZSTR PZZTSTR, PUZZTSTR;
typedef PCZZSTR PCZZTSTR, PCUZZTSTR;
typedef PNZCH PNZTCH, PUNZTCH;
typedef PCNZCH PCNZTCH, PCUNZTCH;
#define __TEXT(quote) quote         // r_winnt

#endif /* UNICODE */                // r_winnt
#define TEXT(quote) __TEXT(quote)   // r_winnt

兼容Unicode和Ansi我们可以用:

TCHAR buffer[126] = {TEXT("MyBuffer")};
HANDLE hFile = CreateFile(TEXT("MyFile")...);
的方式。

2. Windows中Ansi和Unicode的字符串之间的转换

WideCharToMultiByte:

该函数映射一个字符串到一个宽字符(unicode)的字符串

int WideCharToMultiByte(
  UINT CodePage,
  DWORD dwFlags,
  LPCWSTR lpWideCharStr,
  int cchWideChar,
  LPSTR lpMultiByteStr,
  int cbMultiByte,
  LPCSTR lpDefaultChar,
  LPBOOL lpUsedDefaultChar
);

codePage: 指定要转换成的字符集代码页常用的如下:

CP_ACP: 实现了ANSI与Unicode之间的转换。

CP_UTF8:实现了UTF-8与Unicode之间的转换。

dwFlags: 一般设置为0

lpWideCharStr: 待转换的UNICODE字符串

cchWideChar: 待转换的字符串的长度, -1表示转换到字符串结尾。

lpMultiByteStr: 转换后的字符缓冲区

cbMultiByte: 输出缓冲区大小,如果为0,lpMultiByteStr将被忽略,函数将返回所需缓冲区大小而不使用lpMultiByteStr。

lpDefaultChar: 指向字符的指针, 在指定编码里找不到相应字符时使用此字符作为默认字 符代替。 如果为NULL则使用系统默认字符。对于要求此参数为NULL的dwFlags而使用此参数,函数将失败返回并设置错误码ERROR_INVALID_PARAMETER。 

lpUsedDefaultChar:开关变量的指针,用以表明是否使用过默认字符。对于要求此参数为 NULL的dwFlags而使用此参数,函数将失败返回并设置错误码ERROR_INVALID_PARAMETER。lpDefaultChar和lpUsedDefaultChar都设为NULL,函数会更快一些。

返回值: 如果函数成功,且cbMultiByte非0,返回写入lpMultiByteStr的字节数(包括字符串 结尾的null);cbMultiByte为0,则返回转换所需 字节数。函数失败,返回0。

为了避免内存泄漏,宜先使cbMultiByte置为0,获取所需的字节数,再依据字节数申请适当的内存字节数,再调用函数进行转换。

如以下:

//
// 使用完成之后, 记得释放内存
char * UnicodeToAnsi()
{
	wstring unicodeStr = L"UnicodeString字符串";
	
	int nLen = WideCharToMultiByte(CP_ACP, 0, unicodeStr.data(), -1, NULL, 0, NULL, NULL);
	char *pAnsiStr = new char[nLen + 1];

	memset(pAnsiStr, 0, nLen+1);
	WideCharToMultiByte(CP_ACP, 0, unicodeStr.data(), -1, pAnsiStr, nLen, NULL, NULL);

	wcout.imbue(locale("chs"));
	wcout << L"Unicode String: " << unicodeStr << endl;
	cout << "Ansi String: " << pAnsiStr << endl;

	return pAnsiStr;
}

详细参考: 百度文库相关文档

MultiByteToWideChar:

字符串映射到一个宽字符(Unicode)字符串

int MultiByteToWideChar(
  UINT CodePage,
  DWORD dwFlags,
  LPCSTR lpMultiByteStr,
  int cbMultiByte,
  LPWSTR lpWideCharStr,
  int cchWideChar
);
lpMultiByteStr: 待转换的多字节字符串

cbMutliByte: 多字节字符串的长度,如果此参数为-1,函数处理整个输入字符串,包括'\0'终止符

lpWidCharStr: 转换的宽字符指向的缓冲区

cchWidChar: 宽字符缓冲区的大小,以宽字符为单位

返回值:如果函数调用成功,cchWideChar非零,返回值是由lpWideCharStr指向的缓冲区写入宽字符数。 

如果函数调用成功,并cchWideChar为零,返回值是所需的大小,在宽字符,一个缓冲区,可以接收翻译的字符串。

以下为示例:

//
// 使用完成之后, 记得释放内存
wchar_t * AnsiToUnicode()
{
	char *pAnsiStr = "ansi字符串";
	int nLen = MultiByteToWideChar(CP_ACP, 0, pAnsiStr, -1, NULL, 0);
	wchar_t *pUnicodeStr = new wchar_t[nLen + 1];

	memset(pUnicodeStr, 0, (nLen + 1) * sizeof(wchar_t));

	MultiByteToWideChar(CP_ACP, 0, pAnsiStr, -1, pUnicodeStr, nLen);

	cout << "Ansi: " << pAnsiStr << endl;
	wcout.imbue(locale("chs"));
	wcout << L"Unicode: " << pUnicodeStr << endl;

	return pUnicodeStr;
}
详细参考:  百度文库文档


UTF-8字符串与Ansi和Unicode的转换,只需将CP_ACP换成CP_UTF8即可。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值