并不是所有的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 512int _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"";// 定义错误代码22const 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数据类型介绍相关推荐

  1. tchar.h及TCHAR数据类型介绍

    并不是所有的Windows操作系统都支持UNICODE编码的API(例如早期的Windows98), 这就造成了两种结果:某些版本的Windows应该应用wchar_t来保存字符, 某些平台的Wind ...

  2. Redis 数据类型介绍

    Redis 数据类型介绍 你也许已经知道Redis并不是简单的key-value存储,实际上他是一个数据结构服务器,支持不同类型的值.也就是说,你不必仅仅把字符串当作键所指向的值.下列这些数据类型都可 ...

  3. openresty开发系列13--lua基础语法2常用数据类型介绍

    openresty开发系列13--lua基础语法2常用数据类型介绍 一)boolean(布尔) 布尔类型,可选值 true/false: Lua 中 nil 和 false 为"假" ...

  4. redis种类型对应java类型_Redis的五种基本数据类型介绍

    Redis作为缓存具有极其丰富的功能,比如计数器.好友关系以及排行榜等等.而Redis之所能够实现如此强大的功能,完全是依赖着它的基本数据结构.今天我们来看看Redis的五种基本的数据结构,分别是字符 ...

  5. mysql数据库邮箱什么类型_MySQL的数据类型介绍

    MySQL的数据类型介绍 发布时间:2020-06-01 20:57:09 来源:亿速云 阅读:154 作者:鸽子 由于Mysql独有的特性和实现细节对性能的影响是很明显的,因为做好Mysql数据库的 ...

  6. Redis五种数据类型介绍

    概述 Redis的键值可以使用物种数据类型:字符串,散列表,列表,集合,有序集合.本文详细介绍这五种数据类型的使用方法.本文命令介绍部分只是列举了基本的命令,至于具体的使用示例,可以参考Redis官方 ...

  7. DB2日期时间型数据类型介绍

    作者:夏果果出处:博客2011-11-18 07:23 DB2日期时间型数据类型是DB2数据库中的数据类型之一,下面就为您分类介绍DB2日期时间型数据类型,希望对您能有所帮助-- DB2日期时间型数据 ...

  8. java 基本数据类型_Java语言的八种基本数据类型介绍

    本文主要向大家介绍了Java语言的八种基本数据类型介绍,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助. Java的基本数据类型有八种 一,四种整数类型(byte.short.int.l ...

  9. MySQL的存储引擎及常用数据类型介绍

    1. MySQL中的数据库分类 2. MySQL中的存储引擎 MySQL中的数据用各种不同的技术存储在文件(或者内存)中.这些技术中的每一种技术都使用不同的存储机制.索引技巧.锁定水平并且最终提供不同 ...

最新文章

  1. 2018世界人工智能蓝皮书:看中国到底有多强!【附下载】| 智东西内参
  2. 服务器e5系列和e5v4系列,“芯”力量:四款至强E5 v4双路服务器横评
  3. 目标检测基本概念理解之IoU(交并比)以及Python代码实现
  4. 在 SAP BTP Kyma Runtime 上使用 Redis 读取和存储数据
  5. HTML如何添加锚点,论程序员成长的正确姿势
  6. UNIX网络编程——fcntl函数
  7. rust加载不进去服务器eac_基于腾讯云的 Rust 和 WebAssembly 函数即服务
  8. 苹果指控高通从事非法专利授权活动 索赔最高270亿美元
  9. Android network基础知识 — IPv4和IPv6的区别
  10. C# 淘宝商品微信返利助手开发-(一)返利助手原理
  11. matlab残差分析取离散点,matlab残差分析图
  12. 电脑常用快捷键【按使用场景分类】-Windows
  13. MySQL的主键,索引设置和添加
  14. Python之有趣的小程序
  15. 运动目标检测——研究方向与难点
  16. CSDN 如何修改用户名(CSDN ID)?
  17. 61二次型—— 化二次型为标准形、矩阵的合同变换求二次型的标准形
  18. 抓取国家统计局2018年的省市区街道数据
  19. THE ADVENTURE BEGINS
  20. 计算机页面大小4k,4K分辨率到底是什么?简单告诉你

热门文章

  1. 交换机access trunk hybrid模式详解
  2. 5.5.1 jmeter组件-取样器-HTTP请求
  3. [转载]集成电路芯片IC封装技术的发展
  4. 安防监控流媒体服务器对接宇视摄像机配置OCX插件安装时出现Failed to register ocx, error code 14001错误问题分析
  5. 设计模式17-门面模式
  6. 记一次尴尬的调试错误:在形参表中不匹配
  7. border-radius(使用详解)
  8. 紫薇圣人的程序员人生[原创IT小说]
  9. ffmpeg 提取音频,音频转换,添加字幕
  10. vnpy2.0 探索(一)