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.h> 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; }