windows程序设计01_utf8编码问题
坚持与妥协
从学程序的第一天老师就给我们说源代码应该使用utf8保存.因为先入为主,"源代码应该使用utf8"的观念已经在"学院派"出身的程序员脑子里根深蒂固.如果您固执地坚持自己的信仰,坚信源代码应该并且只应该用utf8保存,决不向任何工具或者人妥协!那么恭喜您,可以看看这个文章.
VS2013及以前
utf8是unicode的一种实现方式.windows95及以前,还没有unicode,更没有utf8.所以在windows95及以前微软自己定义了一套解决多国语言的规则(mbcs),因为windows95的巨大成功,大量程序都是用的微软自己定义国语言规则.到windows nt的时候unicode已经出现,所以的windows nt的内核用了unicode编码(UCS-2),内核彻底解决了多国语言.但是为了和已有代码兼容,windows 没有把自己的mbcs废除.mbcs用到什么时候?现在还在用.到VS2017,mbcs还是微软解决的多国语音问题的默认方式.在VS2013的时候,微软建议过不要再使用mbcs(参考资料5),以后的版本可能不再提供.但用户不干了,因为太多的程序是用mbcs的方式,修改成 unicode成本太大.所以到VS2015,mbcs又回来了,并且宣布以后的版本继续支持mbcs.微软那个纠结呀.
VS2015,VS2017
VS2013及以前微软的编译器cl只能支持utf8 with bom(或者是用mbcs的方式,中文用cp936),一直到到vs2015或者vs2017,cl才有一个指定源代码字符编码的选项/source-charset,vs2015以前都没有.vs2015以前用vs写c语言程序用utf8编码(没有bom)会有很多问题.总之感谢微软, late better than never!
使用utf8编码
假设vs2017的安装目录是%VS_HOME%,则用vs打开下面2个文件
%VS_HOME%\Common7\IDE\VC\vcprojectitems\hfile.h
%VS_HOME%\Common7\IDE\VC\vcprojectitems\newc++file.cpp
在这2个文件中加入一行中文注释,如
// utf8编码
然后选择"高级保存选项",然后在编码中选择utf8(无签名)65001.这样再新建文件时,编码都是utf8.
Hello world程序
看C00CmdHelloWorld.c的代码:
// 编码设置为utf-8
#include <stdio.h>
#include <string.h>
int main() {
char* a = "hello";
char* b = "您好";
printf("%s size is %d\n", a, strlen(a));
printf("%s size is %d\n", b, strlen(b));
getchar();
return 0;
}
有2种方式编译运行.
- 命令行
在visual studio tools中打开"develop command prompt for vs2017",进入命令行.切到C00CmdHelloWorld.c所在目录.执行
cl C00CmdHelloWorld.c /source-charset:utf-8
C00CmdHelloWorld
输出为
hello size is 5
您好 size is 4
- 用vs
在vs的工程右键——"属性"——"配制属性"——"C/C++"——"命令行"在其他选项中添加/source-charset:utf-8
再ctrl+F5运行.结果和命令行运行一致.
字符串hello的长度是5,没问题."您好"的长度是4,这个是有问题的. 希望得到的长度是2(因为是2个字符.)如何修改?看C00CmdHelloWorld1.c的代码.
// 编码设置为utf-8
#include <stdio.h>
#include <string.h>
#include <locale.h>
int main() {
_wsetlocale(LC_ALL, L"");
wchar_t* a = L"hello";
wchar_t* b = L"您好";
printf("%ls size is %d\n", a, wcslen(a));
printf("%ls size is %d\n", b, wcslen(b));
getchar();
return 0;
}
这个代码"hello"的长度是5,"您好"的长度是2.wchar_t表示以双字节的方式保存字符.windows用的UCS-2,即以2个字节保存一个字符.这和python2是一样的.但是要兼容以前的程序,单字节的api不能废除掉.微软用了一个技巧,同样一份代码,当没有定义UNICODE宏的时候,使用单字节的api,定义UNICODE宏的时候使用双字节的api.细节见参考资料4的第2章.C00CmdHelloWorld1.c没有用微软这个技巧,显示地指定了用双字节的api.什么时候使用微软这个技巧,什么时候不用?个人建议:
- 程序不需要GUI界面的时候不用,有非ascii码的代码或数据就显式地用wchar_t.所有代码和数据都是ascii码的时候就用char.
- 程序中有GUI界面的时候用微软这个技巧.
GUI消息框的例子
// C03UnicodeMsg.c编码设置为utf-8
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow) {
TCHAR szBuffer[100];
TCHAR* a = TEXT("a中国b");
wsprintf(szBuffer, TEXT("a中国b,len=%d"), _tcslen(a));
MessageBox(NULL, szBuffer, TEXT("Hello world汉字"), MB_OK);
return 0;
}
编译这个程序的命令为:
cl user32.lib gdi32.lib /D UNICODE / source-charset:utf-8
其中UNICODE就微软定义的宏.这个宏存在时TCHAR被定义为wchar_t,这个宏不存在时,TCHAR被定义为char.
参考资料
- Set Source Character Set
- utf-8编码查询
- gbk编码查询
- (美)Charles Petzold著 方敏,张胜,梁路平,赵勇等译,Windows程序设计(第五版 珍藏版),清华大学出版社,2010.
- Continue support for MBCS (Multi-Byte Character Sets) for MFC and C++
windows程序设计01_utf8编码问题的更多相关文章
- Windows程序设计:格式化对话框的设计
刚开始学习Windows程序设计,磕磕碰碰,先做个小笔记缓缓神经,主要是将MessageBox这个Windows API函数的. MessageBox函数是许多人刚开始学习Windows程序设计或者是 ...
- Windows 程序设计
一.Win32 API /******************************************************************** created: 2014/04/1 ...
- 关于《Windows程序设计(第五版)》中一个实例程序的疑问
最近一直在看Charlse Petzold的<Windows程序设计>,作为一个新得不能再新的新手,只能先照着书的抄抄源码了,之前的例子一直都很正常,但昨天遇到一个很诡异的BUG. 先看实 ...
- windows 程序设计自学:添加图标资源
#include <windows.h> #include "resource.h" LRESULT CALLBACK MyWndProc( HWND hwnd, // ...
- windows程序设计笔记
2014.05.06 新建一个visual C++ -- 常规 -- 空白 的项目,用.c后缀名指定这是一个用C语言来写的windows项目.和C语言的hellworld程序做了一个比较,按照wind ...
- 《Windows程序设计第5版》学习进度备忘
书签:另外跳过的内容有待跟进 __________________学习资源: <Windows程序设计第5版珍藏版> __________________知识基础支持: _________ ...
- MFC Windows程序设计源代码免费下载
本人近期在网上找到了<MFC Windows程序设计>第二版的书内程序的源代码,特意上传CSDN上面,供学习MFC的程序猿们免费下载. 源代码下载: http://download.csd ...
- windows 程序设计 SetPolyFillMode关于ALTERNATE、WINDING的详细解释
看windows程序第五章GDI编程部分.一直卡壳在这里了. 下面我来说下自己的想法.看是否对您有帮助. 首先我们来看一个图. SetPolyFillMode(ALTERNATE); // 系统默认 ...
- windows程序设计简介
大家好,非常高兴和大家一起分享Windows开发心得,Windows已经诞生很多年了,一直因为它的简单易用而深受欢迎,相信很多人在使用Windows的时候,一定有这样一个想法:希望自己将来可以写一个很 ...
随机推荐
- ubuntu安装应用日志
1.安装搜狗输入法,去官网下 2.安装vim 3.安装vbox5.16,导入win7(还未成功,报错UUID不匹配),改5.14试试 4.安装微信:http://www.cnblogs.com/Blu ...
- Tarjan-割点
割点——tarjan #include <bits/stdc++.h> using namespace std; ; ; int n, m; int ans;//个数 * MAXM], n ...
- 使用ASP.NET Core 3.x 构建 RESTful API - 3.2 路由和HTTP方法
ASP.NET Core 3.x 的路由 路由机制会把一个请求的URI映射到一个Controller上面的Action,所以当你发送一个HTTP请求的时候,MVC框架会解析这个请求的URI,并尝试着把 ...
- ubantu删除源码安装文件
1.在安装目录下执行 make uninstall (如安装目录为/opt/software/opencv3.1.0/release) 2.删除系统相关文件 cd /usr sudo find . - ...
- python进程池与线程池
为什么会进行池化? 一切都是为了效率,每次开启进程都会分配一个属于这个进程独立的内存空间,开启进程过多会占用大量内存,系统调度也会很慢,我们不能无限的开启进程. 进程池原来大概如下图 假设有100个任 ...
- Java描述设计模式(23):访问者模式
本文源码:GitHub·点这里 || GitEE·点这里 一.生活场景 1.场景描述 电竞是游戏比赛达到"竞技"层面的体育项目.利用电子设备作为运动器械进行的.人与人之间的智力对抗 ...
- 面试官:你连RESTful都不知道我怎么敢要你?
目录 01 前言 02 RESTful的来源 03 RESTful6大原则 1. C-S架构 2. 无状态 3.统一的接口 4.一致的数据格式 4.系统分层 5.可缓存 6.按需编码.可定制代码(可选 ...
- ASP使用ajax来传递中文参数的编码处理
背景 asp的第一版是0.9测试版,自从1996年ASP1.0诞生,迄今20余载.虽然asp在Windows2000 IIS服务5.0所附带的ASP 3.0发布后好像再没有更新过了,但是由于其入手简单 ...
- tcpip协议
几个概念 1.分层(我们使用四层模型更为贴合我们的实际网络) 分层是为什么,其实和公司中职位是一样的,不同职位的人做不同的事情,然后不同职位的人合起来,一起完成了数据传输的事情. 链路层 在这个层面 ...
- webpackd学习的意义
高速发展的前端技术,与浏览器支持的不相匹配.导致前端必须把前端比较先进的技术进行一层编码从而使得浏览器可以加载. 比如前端框架Vue,Angular,React.Less,Sass.TypeScrip ...