1 2 3 4 5 6 0x41 0x80 0x51 0x42 0x82 0x53 A 中 B 国
这样既包含多字节又包含单字节的成为多字节编码
#ifndef _UNICODE typedef char TCHAR #define __T(x) x #else typedef wchar_t TCHAR #define __T(x) L##x #endif
代码使用:使用UNICODE宏开关,通知
编译器选择编译的代码.
#ifndef _UNICODE int nLen = strlen( pszText ); #else int nLen = wcslen( pszText ); #endif
BOOL WriteConsole( HANDLE hConsoleOutput, //控制台输出流的句柄 CONST VOID *lpBuffer,//输出的字符串的指针 DWORD nNumberOfCharsToWrite,//输出的字符串的长度 LPDWORD lpNumberOfCharsWritten, // 返回已输出字符的数量 LPVOID lpReserved ); // 保留值
#include "stdafx.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include <windows.h> #include <tchar.h> //TCHAR void ascii() { for(int i=0;i<255;i++) { printf("%c ",i); } printf("\n"); //因为现在是中文字符集 而中文是双字节的 所以 128以后的都变成问号了 } void codePage(int nCodePage) { /* BOOL SetConsoleCP( UINT wCodePageID // code page to set ); 437 美国 936 中国 */ SetConsoleOutputCP(nCodePage); for(int i=0;i<255;i++) { printf("%c ",i); } printf("\n"); } void c_char() { char *pszText = "hello world"; int nLen = strlen(pszText); printf("%d,%s\n",nLen,pszText); } void c_wchar() { SetConsoleOutputCP(936); wchar_t cText = 'A'; //char 可以指直接转换为wchar_t // wchar_t *pszText = "ABCD"; 错误 无法从const char[5] 转换成wchar_t * wchar_t *pszText = L"ABCD"; //L告诉编译器 字符串是双字节字符串 int nLen = wcslen(pszText); // 这里是4 和以前一样 表示有4个双字节 //printf("%s\n",pszText); //发现只打印了A 因为A的aci是41 变成双字节后 在小端模式内存中是 41 00 所以按单字节打印时只显示A了 查看内存方法 调试-窗口-内存 wprintf(L"%d,%s\n",nLen,pszText);// 格式化输出之前要写个L //宽字节字符串 wchar_t *pszChs = L"我是程序员"; nLen = wcslen(pszChs); wprintf(L"%d,%s\n",nLen,pszChs); //5 ???? printf 对unicode的支持不高 所以汉字打印不出来 //多字节字符串 char * ptr = "我是程序员"; nLen = strlen(ptr); printf("%d,%s\n",nLen,ptr); //10 我是程序员 } void tchar() { TCHAR *pszText = __T("我是程序员"); // __T 根据是否是unicode在前面加L #ifndef _UNICODE int len = strlen(pszText); #else int len = wcslen(pszText); #endif printf("%d\n",len); } void printUnicode(wchar_t *pszStr) { //如何打印UNICODE WINDOWS API /* BOOL WriteConsole( HANDLE hConsoleOutput, // handle to a console screen buffer CONST VOID *lpBuffer, // pointer to buffer to write from DWORD nNumberOfCharsToWrite, // number of characters to write LPDWORD lpNumberOfCharsWritten, // pointer to number of characters written LPVOID lpReserved // reserved ); */ HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE); //得到console的句柄 int nLen = wcslen(pszStr); WriteConsole(hout,pszStr,nLen,NULL,NULL); /* //将所有的unicode打印出来 wchar_t szText[2] = {0}; for(BYTE nHigh=0;nHigh<0xFF;nHigh++) { for(BYTE nLow=0;nLow<0xFF;nLow++) { szText[0] = MAKEWORD(nLow,nHigh); //宏 MAKEWORD 构成一个字 WriteConsole(hout,szText,wcslen(szText),NULL,NULL); } } */ } int _tmain(int argc, _TCHAR* argv[]) { printf("hello world\n"); c_char(); ascii(); printf("----------------------\n"); codePage(437); c_wchar(); tchar(); printUnicode(L"我是程序员\n"); system("pause"); return 0; }
多字节到宽字节
int MultiByteToWideChar(
UINT CodePage,// 代码页
DWORD dwFlags,// 转换方式
LPCSTR lpMultiByteStr, // 需要被转换CHAR地址
int cchMultiByte,//需要被转换CHAR的长度
LPWSTR lpWideCharStr,//用于存放转换后的结果BUFF
int cchWideChar );//BUFF的长度
使用方法:
1 将要转换的字符串,传递给函数(cchWideChar 或者 cchMultiByte = 0),从 返回值中获取转换后字符串的元素个数。
2 分配字符串空间
3 再次调用函数,并将分配的空间传递给函数,获取结果.
4 例子
void MyMessageBox() { MessageBox(NULL,TEXT("helloWide"),TEXT("宽的"),MB_OK); } void Multi2Wide() { CHAR * pszText = "MultiByte"; //先测算一次长度 int nLen = MultiByteToWideChar(CP_ACP,0,pszText,strlen(pszText),NULL,0); // 拿到长度后分配空间 wchar_t *pwszText = (wchar_t *)malloc((nLen+1)*sizeof(wchar_t)); //多一个wchar空间来存放\0\0 memset(pwszText,0,(nLen+1)*sizeof(wchar_t)); //再进行转换 MultiByteToWideChar(CP_ACP,0,pszText,strlen(pszText),pwszText,nLen); MessageBoxW(NULL,pwszText,TEXT("Multi2Wide"),MB_OK); free(pwszText); }; void Wide2Multi() { WCHAR *pwszText = TEXT("Widebyte"); int nLen = WideCharToMultiByte(CP_ACP,0,pwszText,wcslen(pwszText),NULL,0,NULL,0); char *pszText = (char*)malloc((nLen+1)*sizeof(char)); memset(pszText,0,(nLen+1)*sizeof(char)); WideCharToMultiByte(CP_ACP,0,pwszText,wcslen(pwszText),pszText,nLen,NULL,0); MessageBoxA(NULL,pszText,"Wide2Multi",MB_OK); };