字符编码--字符与数字的对应

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


 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值