前言:从Windows NT/2000开如,Windows系统已经是一个标准的UNICODE系统,系统内部所有字符串存储及操作均使用UNICODE编码。因此Win32 API都是UNICODE版本的,但为了更好的本地化支持,也提供了MBCS(ANSI)版的Win32 API。UNICODE版Win32 API形式为xxxW,W(Wide)代表宽字符;MBCS(ANSI)版Win32 API形式为xxxA,A即ANSI。xxxA形式的Win32 API在被调用时,会先调用先根据“代码页转换表”执行由ANSI——UNICODE的转换,然后再调用xxxW形式的Win32 API去执行实际操作。即xxxA形式的Win32 API在被调用时只是先执行ANSI——UNICODE转换功能,然后再调用xxxA形式的Win32 API。

  同样,Windows控制台也是标准的UNICODE系统功能,也有xxxA,xxxW两种对其操作的Win32 API,下面以WriteConsole为例。它也存在WriteConsoleA和WriteConsoleW两上版本,但我们在MSDN中找不到这两个原型型,可以在C:\Program Files\Microsoft Visual Studio\VC98\Include\WINCON.H在可以发现它的定义,并可以发现对它们进行控制的预定义语句。

#ifdef UNICODE

#define WriteConsole WriteConsoleW

#else

#define WriteConsole WriteConsoleA

#endif

一、Windows控制台输出

我们可以通过下面代码进行测试:

wchar_t test[] = L"测试1234";
DWORD ws;
WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE),test,wcslen(test),&ws,NULL);

//正确输出“测试1234”

char test[] = "测试1234";
DWORD ws;
WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE),test,wcslen(test),&ws,NULL);

//正确输出“测试1234”

若我们调用C库函数,可能会遇到点问题:

char test[] = "测试1234";

printf(test);

cout<<test;

//正确输出“测试1234”

wchar_t test[] = L"测试1234";

wprintf(test);

wcout<<test;

//什么也没输出

  这是因为wprintf、wcout并不是真是意义上的支持UNICODE,它和printf、wcout一样内部调用都是xxxA版的Win32 API(如WriteConsoleA),只不过它们是先依据指定的“代码页转换表”,把UNICODE字符串转化为ANSI字符串,再去调用xxxA版的Win32 API。

setlocale(LC_ALL,"chs");

wchar_t test[] = L"测试1234";

wprintf(test);

wcout<<test;

//正确输出“测试1234”

整个过程可以这样描述:

GBK——————UNICODE ——————GBK——————UNICODE——————

L""                wcout       xxxA API        xxxW API

二、Windows控制台输入

  仅从编码方式上讲,在Windows控制台进行字符输入,和在记事本、WORD中进行字符输入是一样的,字符存储的编码由输入法的编码方式决定。在简体中文XP上,我们使用“智能ABC”在文本中输入“ab中国”,当以二进制方式打开时,可以发现里面的二进制内容(GBK编码)为:

61 62 D6 D0 B9 FA

a   b     中  国

只是我们可以在取得到字符的内存拷贝后,可以用相关函数进行转换和操作。

三、文件的读写

  与其它关系到系统显示或控制函数不同,文件的读写函数不会关心系统的字符编码方式,只是的执行“内存——外存”的字节拷贝,与字符集的使用无关,故只提了一个版本。但有意思的是文件的创建和删除都有两版本,因为它涉及到了系统内部编码。

CreateFileA CreateFileW

DeleteFileA DeleteFileW

ReadFile 

WriteFile

  我们应注意“字符的存储”与“字符的显示”在编码方式上是独立的。例如使用UNICODE编码的Windows系统,“字符的显示”当然是UNICODE编码,但“字符的存储”则由用户决定,可以是ANSI(GB2312, GBK, JIS……)、也可以是UTF-16、UTF-32、UTF-8等。当采用非UNICODE编码并调用xxxA形式的win32 API时,Windows在显示时会先根据“代码页转换表”执行由ANSI——UNICODE的转换。

windows控制台程序——关于UNICODE字符的总结(转)的更多相关文章

  1. VS2017新建windows控制台程序打印中文乱码问题

    最近刚换上VS2017,由于手头又要做个MFC的程序,所以写控制台程序做功能测试,然后发现居然乱码了. 于是用VS2017新建windows控制台应用程序,在main函数种加一句printf(&quo ...

  2. c程序实现unicode字符转utf-8字符

    下面是一个unicode字符转换为utf-8的c程序实现: /* * ================================================================= ...

  3. Windows控制台程序“选定模式”的问题

    最近用Nodejs写了个代理程序,一直用的好好的,木有问题,今天突然发现不能用了,使用telnet去连代理的端口也能连通,可是服务就是不能正常使用,提示连接超时. 当时猜测是Nodejs的某个地方阻塞 ...

  4. c#中重定向windows控制台程序的输出信息

    这个问题来自论坛提问,答案如下.这只是一个简单的ipconfig命令.如果是复杂的,比如oracle的exp之类的命令,能在调用的时候显示出来,还是相当酷的. using System; using ...

  5. 你们信不信一句Console.WriteLine就能让你的控制台程序失去响应

    好久没更新博客了,今天是扒衣见君节,难得闲下来就来说说一个最近有趣的发现吧. 首先废话不多说,直接上代码吧 class Program { static void Main(string[] args ...

  6. 如何利用java把文件中的Unicode字符转换为汉字

    有些文件中存在Unicode字符和非Unicode字符,如何利用java快速的把文件中的Unicode字符转换为汉字而不影响文件中的其他字符呢, 我们知道虽然java 在控制台会把Unicode字符直 ...

  7. Windows 程序支持 Unicode

    宽字符 阅读了 UTF-8 Everywhere 一文,推荐在程序中对于字符串都使用 UTF-8 编码.Unix-like 系统默认是支持 UTF-8 编码的Unicode字符串,标准库函数也默认支持 ...

  8. C Windows控制台字符版本俄罗斯方块

    //一个可以工作在Windows控制台字符界面下的俄罗斯方块 //工作在非图形模式,无需其他库依赖,单个C文件代码即可运行 //支持最高纪录,并且对于纪录进行了加密 //By wrule 2015年1 ...

  9. [C/C++]宽字符与控制台程序

    转自:http://www.cnblogs.com/zplutor/archive/2010/11/27/1889227.html 在我刚开始学C/C++的时候,字符类型使用的都是char.接触Win ...

随机推荐

  1. 28 Data Race Detector 数据种类探测器:数据种类探测器手册

    Data Race Detector 数据种类探测器:数据种类探测器手册 Introduction Usage Report Format Options Excluding Tests How To ...

  2. Registry私有仓库搭建及认证

    本节内容: Registry相关概念 Registry V1和V2 安装Docker 搭建本地registry v2 搭建外部可访问的Registry 添加认证 更高级的认证 registry web ...

  3. Ansible之迭代、模板

    本节内容: 迭代 模板(JInjia2相关) Jinja2相关 一.迭代 当有需要重复性执行的任务时,可以使用迭代机制.其使用格式为将需要迭代的内容定义为item变量引用,并通过with_items语 ...

  4. day2编写购物商城(1)

    作业:购物商城 商品展示,价格 买,加入购物车 付款,钱不够     具体实现了如下功能: 1.可购买的商品信息显示 2.显示购物车内的商品信息.数量.总金额 3.购物车内的商品数量进行增加.减少和商 ...

  5. Linux下文件压缩与打包

    Linux常用压缩命令compresscompress压缩出来的文件的后缀是.Z,解压命令是ucompresscompress -c 文件 > 压缩后的文件名 ,选项-v显示压缩过程,选项-c的 ...

  6. 2017-2018 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) M - Unsatisfying 2-Sat

    题目大意:给你 m 个式子, 问你最少再添加多少式子能使没有任何一种赋值方式使全部的式子为真. 并且在你给的式子中不能有非. 思路:根据题目给的m个式子可以建出2-Sat的图, 现在问你最少加多少个边 ...

  7. TradingView 为 k 线柱添加标记

    看别人翻译的开发文档: 开发文档地址:https://zlq4863947.gitbooks.io/tradingview/ getMarks(symbolInfo, startDate, endDa ...

  8. ref:Mysql授权远程登陆

    ref:https://blog.csdn.net/qq_26710805/article/details/79776897 在Windows环境上操作.步骤如下: 1. 打开cmd窗口,登陆mysq ...

  9. Logan:美团点评的开源移动端基础日志库

    前言 Logan是美团点评集团移动端基础日志组件,这个名称是Log和An的组合,代表个体日志服务.同时Logan也是“金刚狼”大叔的名号,当然我们更希望这个产品能像金刚狼大叔一样犀利. Logan已经 ...

  10. redis 发布/订阅 模式

    发布/订阅模式的命令如下: * 进入发布订阅模式的客户端,不能执行除发布订阅模式以上命令的其他命令,否则出错.