TCHAR数据类型介绍
转载:https://blog.csdn.net/mousebaby808/article/details/5259944
并不是所有的Windows操作系统都支持UNICODE编码的API(例如早期的Windows98), 这就造成了两种结果:某些版本的Windows应该应用wchar_t来保存字符, 某些平台的Windows应该使用char类型来保存字符, 显然这两种类型的变量是无法混用的。
为了解决该问题, Windows从一开始设计Windows时, 就提供了一整套方案, 对于支持ASCII字符集的API函数, 函数使用字母A作为后缀;对于支持UNICODE字符集的API函数, 则使用字母W作为后缀。例如:FormatMessage函数就提供了FormatMessageA和FormatMessageW两个版本。
文档记载及我们使用的API函数, 实际是定义在Windows.h文件中的一组“宏”, 这组宏在UNICODE环境下将调用函数映射为后缀为W的函数;在ASCII环境下将调用函数映射为后缀为A的函数。
tchar.h头文件提供了一个数据类型TCHAR, 这个类型在UNICODE环境下将映射为wchar_t类型;在ASCII环境下映射为char类型。另外, tchar.h还提供了一组C语言字符串操作符的替代宏, 以_t开头, 例如_tcslen函数, 在UNICODE环境下被映射成为wcslen函数, 在ASCII环境下被映射成为strlen函数。
最后, tchar.h提供了_T宏, 该宏具有一个字符串类型参数, 在UNICODE环境下, 该宏会为字符串前面加上L符号。
- // 定义宏UNICODE和_UNICODE, 一旦定义了该宏, C语言编译器将在UNICODE环境下工作
- // 注意, 一般情况下需要定义UNICODE宏和_UNICODE宏, 因为不同版本的C编译器要求不同
- // 在正式工作时, 并不需要定义这两个宏, 只需要在"项目属性->配置属性->字符集"中选择
- // UNICODE字符集或是多字节字符集即可, 开发环境会自动定义相应的宏
- #if !defined(UNICODE)
- #define UNICODE
- #endif
- #if !defined(_UNICODE)
- #define _UNICODE
- #endif
- // 在所有头文件之前包含tchar.h头文件
- // 这是程序可以应用各类替代宏的基础
- #include <tchar.h>
- #include <locale.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <windows.h>
- /**
- * 显示一个字符, ASCII版本
- * 参数:c, 要显示的字符变量
- */
- void ShowCharacterA(char c)
- {
- // 在ASCII版本中, 选用printf函数来显示字符串
- printf("(A)字符 %c 占据空间 %d", c, sizeof(c));
- }
- /**
- * 显示一个字符, UNICODE版本
- * 参数:c, 要显示的字符变量
- */
- void ShowCharacterW(wchar_t wc)
- {
- // 在UNICODE版本中, 选用wprintf函数来显示UNICODE字符串
- wprintf(L"(W)字符 %c 占据空间 %d", wc, sizeof(wc));
- }
- /**
- * 显示一个字符串, ASCII版本
- * 参数:lpcsz, 要显示的字符变量
- */
- void ShowStringA(const char* lpcsz)
- {
- // 在ASCII版本中, 选用printf函数来显示ASCII字符串,
- // 选用strlen函数来测量字符串长度
- printf("/n(A)字符串 %s 长度为%d", lpcsz, strlen(lpcsz));
- }
- /**
- * 显示一个字符串, UNICODE版本
- * 参数:lpcwsz, 要显示的字符变量
- */
- void ShowStringW(const wchar_t* lpcwsz)
- {
- // 在UNICODE版本中, 选用wprintf函数来显示UNICODE字符串,
- // 选用wcslen函数来测量字符串长度
- wprintf(L"/n(W)字符串 %s 长度为%d", lpcwsz, wcslen(lpcwsz));
- }
- // 下面这一组编译器指令, 根据是否定义UNICODE(或_UNICODE)宏, 映射不同的函数
- // 可以删除#if和#endif之间的代码, 查看运行结果的变化, 思考产生这种变化的原因
- #if defined(UNICODE) | defined(_UNICODE)
- // 定义ShowCharacter宏映射到ShowCharacterW函数
- #define ShowCharacter ShowCharacterW
- // 定义ShowString宏映射到ShowStringW函数
- #define ShowString ShowStringW
- #else
- // 定义ShowCharacter宏映射到ShowCharacterA函数
- #define ShowCharacter ShowCharacterA
- // 定义ShowString宏映射到ShowStringA函数
- #define ShowString ShowStringA
- #endif
- // 定义缓冲区长度为512个字符
- #define BUF_LEN 512
- int _tmain(int argc, TCHAR* argv[])
- {
- // 定义变量, 保存字符
- TCHAR c = _T('A');
- // 定义字符数组, 保存字符串
- TCHAR szStr[] = _T("ABC大家好");
- // 定义指向字符串的指针
- TCHAR* lpszStr = _T("Hello你好");
- // 定义指向字符串的常量指针
- const TCHAR* lpcszStr = _T("GoodBye再见");
- int bSame;
- // 定义BUF_LEN长度的字符数组作为缓冲区
- TCHAR szBuffer[BUF_LEN] = _T("");
- // 定义ASCII字符集缓冲区
- char szBufferA[BUF_LEN] = "";
- // 定义UNICODE字符集缓冲区
- wchar_t szBufferW[BUF_LEN] = L"";
- // 定义错误代码22
- const int nError = 22;
- // 设置语言环境为中文
- _tsetlocale(LC_ALL, _T("zhi"));
- // 调用ShowCharacter宏
- ShowCharacter(c);
- // 调用ShowCharacter宏
- ShowString(szStr);
- ShowString(lpszStr);
- ShowString(lpcszStr);
- // _tcsicmp是tchar.h中定义的宏,
- // 在不同的字符集环境下映射为stricmp或wcsicmp函数
- bSame = _tcsicmp(lpszStr, lpcszStr);
- if (bSame == 0)
- {
- // _tprintf是tchar.h中定义的宏, 在不同字符集环境下映射为printf或wprintf函数
- _tprintf(_T("/n字符串 %s 与 %s 相同"), lpszStr, lpcszStr);
- }
- else
- _tprintf(_T("/n字符串 %s 与 %s 不同"), lpszStr, lpcszStr);
- // _tcscpy_s是tchar.h中定义的宏,
- // 在不同字符集环境下映射为strcpy_s或wcscpy_s函数(_s表示安全版本函数)
- _tcscpy_s(szBuffer, BUF_LEN, lpszStr);
- // _tcscat_s是tchar.h中定义的宏,
- // 在不同字符集环境下映射为strcat_s或wcscat_s函数(_s表示安全版本函数)
- _tcscat_s(szBuffer, BUF_LEN, lpcszStr);
- // _tcslen是tchar.h中定义的宏,
- // 在不同字符集环境下映射为strlen或wcslen函数
- _tprintf(_T("/n字符串 %s 长度为 %d"), szBuffer, _tcslen(szBuffer));
- // 接下来, 我们看一下FormatMessage函数在不同环境下的应用
- // ASCII环境下应用, 第5个参数使用char类型数组作为缓冲
- FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, nError, 0, szBufferA, BUF_LEN, NULL);
- printf("/n错误信息:%s", szBufferA);
- // UNICODE环境下应用, 第5个参数使用wchar_t类型数组作为缓冲
- FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, nError, 0, szBufferW, BUF_LEN, NULL);
- wprintf(L"错误信息:%s", szBufferW);
- // 自适应环境, 第5个参数使用TCHAR类型数组作为缓冲
- FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, nError, 0, szBuffer, BUF_LEN, NULL);
- _tprintf(_T("错误信息:%s"), szBuffer);
- _tprintf(_T("/n"));
- system("pause");
- return 0;
- }
TCHAR数据类型介绍的更多相关文章
- Redis常用数据类型介绍、使用场景及其操作命令
Redis常用数据类型介绍.使用场景及其操作命令 本文章同时也在cpper.info发布. Redis目前支持5种数据类型,分别是: 1.String(字符串) 2.List(列表) 3.Hash(字 ...
- Hadoop数据类型介绍
我们知道hadoop是由Java 编程写的.因此我们使用Java开发环境来操作HDFS,编写mapreduce也是很自然的事情.但是这里面hadoop却对Java数据类型进行了包装,那么hadoop的 ...
- C 各种数据类型介绍
1.各种数据类型介绍: 基本数据类型最主要的特点是,其值不可以再分解为其它类型.也就是说,基本数据类型是自我说明的. 1.1整型 整形包括短整型.整形和长整形. 1.1.1短整形 short a=1; ...
- 以太坊智能合约 Solidity 的常用数据类型介绍
目录 目录 1.数组 1.1.对数组的增删改查操作. 2.String.Bytes.Mapping的使用 3.Enums 和 Structs 的简单应用 4.Ether 单位和 Time 单位 5.A ...
- MySQL:数据类型介绍
数据类型介绍 一.整数类型(可以添加自增约束条件) 数据类型 存储需要 有符号 无符号 tinyint 1个字节 -2^7~2^7-1 0~2^8 smallint 2个字节 -2^15~2^15-1 ...
- openresty开发系列13--lua基础语法2常用数据类型介绍
openresty开发系列13--lua基础语法2常用数据类型介绍 一)boolean(布尔)布尔类型,可选值 true/false: Lua 中 nil 和 false 为"假" ...
- SQL数据类型介绍
在计算机中数据有两种特征:类型和长度.所谓数据类型就是以数据的表现方式和存储方式来划分的数据的种类. 在SQL Server 中每个变量.参数.表达式等都有数据类型.系统提供的数据类型分为几大类 ...
- mysql数据类型介绍
一.int.bigint.smallint 和 tinyint的区别详细介绍 bigint 从 -2^63 (-9223372036854775808) 到 2^63-1 (9223372036854 ...
- MySQL 中的数据类型介绍(转)
据我统计,MySQL支持39种(按可使用的类型字段统计,即同义词也作多个)数据类型.下面的介绍可能在非常古老的mysql版本中不适用. 转载出处:http://blog.csdn.net/anxpp/ ...
随机推荐
- ssm框架(Spring Springmvc Mybatis框架)整合及案例增删改查
三大框架介绍 ssm框架是由Spring springmvc和Mybatis共同组成的框架.Spring和Springmvc都是spring公司开发的,因此他们之间不需要整合.也可以说是无缝整合.my ...
- HttPServletRequest 对象 基本应用
HttPServletRequest 对象 基本应用 防盗链 获取Referer这个消息头,判断Referer是不是从指定页面来的.如果不是从指定页面的,跳转回指定页面. 这可以用于保证页面广告的观看 ...
- P2414 [NOI2011]阿狸的打字机 AC自动机
题意 给定n个模式串,有m个询问,每次询问第X个模式串在第Y个模中出现了多少次 解题思路 以fail树相反的方向建一棵树T,问题转化为X的子树中有多少个y的终止节点.跑出T的dfs序,X的子树就可以表 ...
- Python之根据四个坐标确定其位于左上下右上下
1.导入模块 import numpy as np 2.存储所需要确定位置的四个坐标点 # 所需要确定位置的四个坐标 coordinate = [[2570, 1948], [2391, 1919], ...
- three.js尝试(二)模拟游戏开发:3D人物在地图上行走
本次尝试,模拟了一个小人物在场景中行走,使用简单模型建立了森林,图片纹理模拟草地,加载3D模型呈现人物,使用按键asdw模拟人物的行走,行走和站立时人物的切换等. 主要用到点:3D模型的加载,模型的动 ...
- 2018.12.08【NOIP提高组】模拟B组总结(未完成)
2018.12.08[NOIP提高组]模拟B组总结 diyiti 保留道路 进化序列 B diyiti Description 给定n 根直的木棍,要从中选出6 根木棍,满足:能用这6 根木棍拼出一个 ...
- Knowledge 1:Propositional Logic 命题逻辑基础及符号
Keywords reasoning 推理 Deductive reasoning(for a basic logic) 演绎推理 analogy 类比:比喻 /əˈnælədʒi/ definiti ...
- Ansible常用模块介绍及使用(2)
Ansible模块 在上一篇博客<Ansible基础认识及安装使用详解(一)–技术流ken>中以及简单的介绍了一下ansible的模块.ansible是基于模块工作的,所以我们必须掌握几个 ...
- MATLAB 与 Excel 接口
MATLAB 与 Excel 接口MATLAB 与 Excel 有两种接口方式:一种是通过 MATLAB 提供的 Excel 生成器,生成220 MATLAB 实用教程DLL 组件和 VBA 代码,实 ...
- Java线程阻塞方法sleep()和wait()精炼详解
版权声明:因为个人水平有限,文章中可能会出现错误,如果你觉得有描述不当.代码错误等内容或者有更好的实现方式,欢迎在评论区告诉我,即刻回复!最后,欢迎关注博主!谢谢 https://blog.csdn. ...