1 ASC
7位二进制数表示一个字符,共128个字符。
英语字母大小写、阿拉伯数字、标点符号。
2 ASCII
American Standard Code for Information Interchange美国信息交换标准代码
8位二进制数表示一个字符,共256个字符。增加欧洲语言字符。
通过代码页(CodePage)标识不同的字符集。
不同字符集的前128个字符都相同,后128个字符因不同语言而异。
英语 - 437
中文 - 936
通过SetConsoleOutputCP函数设置控制台的代码页。
3 MBCS/DBCS
Multi-Byte Character Set/Double-Byte Character Set
多字节字符集/双字节字符集
用1个或2个字节表示一个字符。单双字节混合容易出现乱码。
C语言
-- ----- -----
43 D3 EF D1 D4
----- ----- --
<乱码>
strlen函数返回5。
4. UNICODE/UCS-2
Universal CODE/Universal Character Set with 2 bytes
通用码/2字节通用字符集
1) 统一用2个字节表示一个字符。
某些字符中可能含有空字符,需要特殊的处理函数。
C语言
----- ----- -----
43 00 ED 8B 00 8A
^^^^
strlen函数返回1。
wcslen函数返回3。
2) 宽字符字符串:每个字符占2个字节,采用UNICODE码。
A. 宽字符类型wchar_t:实际是unsigned short类型,
取值范围从0到65536,相应的字符串字面值需要加“L”。
B. 支持wchar_t类型的字符串函数:wcslen、wprintf,等等。
如:
wchar_t wsText[] = L"Hello World";
wprintf (L"%s, %u, %u\n",wsText, wcslen (wsText), sizeof (wsText));
注意:字符串长度不同于字符串的字节数。
宽字符字符串同样要以空字符结尾,宽字符的空为wchar_t类型的0,即两个0字节。
3) 同时支持多字节(MBCS/DBCS)字符串和宽字符(UNICODE/UCS-2)字符串的代码。
系统头文件tchar.h中包含类似下面的代码:
#ifdef _UNICODE
typedef wchar_t TCHAR;
#define _T(x) L##x
#define _tcslen wcslen
#define _tprintf wprintf
...
#else
typedef char TCHAR;
#define _T(x) x
#define _tcslen strlen
#define _tprintf printf
...
#endif // _UNICODE
同时支持多字节和宽字符的代码:
#include
TCHAR szText[] = _T ("Hello World");
_tprintf (_T ("%s, %u, %u\n"),szText, _tcslen (szText), sizeof (szText));
Project/Settings.../C/C++/Preprocessor definitions中的预定义宏:
_MBCS表示多字节,_UNICODE和UNICODE表示宽字符。
4) UNICODE编码的汉字打印
A. 汉字的UNICODE编码范围从0x4E00到0x9FA5,共20902个字符。
B. wprintf对UNICODE编码的汉字字符打印的支持不够完善。
C. 用WriteConsoleW函数打印UNICODE编码的汉字。
输出字符串到标准输出:
BOOL WINAPI WriteConsoleW (
HANDLEhConsoleOutput,// 标准输出句柄(类似标准I/O流的stdout指针)
const VOID* lpBuffer,// 输出内容缓冲区
DWORDnNumberOfCharsToWrite, // 输出内容的字符数(不是字节数)
LPDWORDlpNumberOfCharsWritten, // 实际输出的字符数
LPVOIDlpReserved// 保留,NULL
);
成功返回TRUE,失败返回FALSE。
获取标准句柄:
HANDLE WINAPI GetStdHandle (
DWORD nStdHandle
);
STD_INPUT_HANDLE - 标准输入句柄
STD_OUTPUT_HANDLE - 标准输出句柄
STD_ERROR_HANDLE - 标准出错句柄
成功返回相应的句柄,失败返回INVALID_HANDLE_VALUE。
写个例子:
// WinChar.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
void CChar (void)
{// 普通char
char szText[] = "C character";
printf ("%s\n", szText);
}
void ASCIIChar (UINT uCodePageID = 0)
{// ASCII
if (uCodePageID > 0)
SetConsoleOutputCP (uCodePageID);//设置代码页
for (int i = 0; i < 256; ++i)// 打印字符集
printf ("%3d : %c\n", i, i);
}
void GBKChar (void)
{// GBK
char szText[] = "天下无敌";
// char szText[] = "withoutcompare";
printf ("%s\n", szText);
printf ("%s\n", szText+1);
printf ("%u\n", strlen ("今天是2014年7月20日")); // 12
}
void UCS2Char (void)
{ UNICODE
// wchar_t szText[] = L"C Language";
wchar_t szText[] = L"C 语言";
/*
printf ("%s, %u, %u\n",
(char*)szText, strlen ((char*)szText),
sizeof (szText));
*/
/*
wprintf (L"%s, %u, %u\n",
szText, wcslen (szText),
sizeof (szText));
*/
HANDLE hOutput = GetStdHandle (STD_OUTPUT_HANDLE);
WriteConsoleW (hOutput, szText, wcslen (szText),NULL, NULL);
}
void TChar (void)
{
/*
char szText[] = "T character";
printf ("%s, %u, %u\n", szText,
strlen (szText), sizeof (szText));
*//*
wchar_t szText[] = L"T character";
wprintf (L"%s, %u, %u\n", szText,
wcslen (szText), sizeof (szText));
*/
TCHAR szText[] = _T("T character");
_tprintf (_T("%s, %u, %u\n"), szText,
_tcslen (szText), sizeof (szText));
}
void PrintHan (void)
{// 打印所有汉字
HANDLE hOutput = GetStdHandle (STD_OUTPUT_HANDLE);
for (WCHAR wcHan = 0x4E00; wcHan <= 0x9FA5; ++wcHan)
WriteConsoleW (hOutput, &wcHan, 1, NULL, NULL);
printf ("\n");
}
int main (int argc, char* argv[])
{
// CChar ();
// ASCIIChar (437);
// ASCIIChar (936);
// ASCIIChar ();
// GBKChar ();
// UCS2Char ();
// TChar ();
PrintHan ();
return 0;
}