TCHAR数据类型介绍

摘要:
我们使用的文档和API函数实际上是在Windows H文件中定义的一组“宏”。这组宏将调用函数映射到UNICODE环境中带有W后缀的函数;将调用函数映射到ASCII环境中后缀为A的函数。查尔。h头文件提供了一个数据类型TCHAR,它在UNICODE环境中映射到wchar _ T类型;映射到ASCII环境中的字符类型。最后,tchar H提供了一个带有字符串类型参数的T宏。在UNICODE环境中,宏将在字符串前面加上L符号。

转载: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符号。

  1. // 定义宏UNICODE和_UNICODE, 一旦定义了该宏, C语言编译器将在UNICODE环境下工作
  2. // 注意, 一般情况下需要定义UNICODE宏和_UNICODE宏, 因为不同版本的C编译器要求不同
  3. // 在正式工作时, 并不需要定义这两个宏, 只需要在"项目属性->配置属性->字符集"中选择
  4. // UNICODE字符集或是多字节字符集即可, 开发环境会自动定义相应的宏
  5. #if !defined(UNICODE)
  6. #define UNICODE
  7. #endif
  8. #if !defined(_UNICODE)
  9. #define _UNICODE
  10. #endif
  11. // 在所有头文件之前包含tchar.h头文件
  12. // 这是程序可以应用各类替代宏的基础
  13. #include <tchar.h>
  14. #include <locale.h>
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <windows.h>
  18. /**
  19. * 显示一个字符, ASCII版本
  20. * 参数:c, 要显示的字符变量
  21. */
  22. void ShowCharacterA(char c)
  23. {
  24. // 在ASCII版本中, 选用printf函数来显示字符串
  25. printf("(A)字符 %c 占据空间 %d", c, sizeof(c));
  26. }
  27. /**
  28. * 显示一个字符, UNICODE版本
  29. * 参数:c, 要显示的字符变量
  30. */
  31. void ShowCharacterW(wchar_t wc)
  32. {
  33. // 在UNICODE版本中, 选用wprintf函数来显示UNICODE字符串
  34. wprintf(L"(W)字符 %c 占据空间 %d", wc, sizeof(wc));
  35. }
  36. /**
  37. * 显示一个字符串, ASCII版本
  38. * 参数:lpcsz, 要显示的字符变量
  39. */
  40. void ShowStringA(const char* lpcsz)
  41. {
  42. // 在ASCII版本中, 选用printf函数来显示ASCII字符串,
  43. // 选用strlen函数来测量字符串长度
  44. printf("/n(A)字符串 %s 长度为%d", lpcsz, strlen(lpcsz));
  45. }
  46. /**
  47. * 显示一个字符串, UNICODE版本
  48. * 参数:lpcwsz, 要显示的字符变量
  49. */
  50. void ShowStringW(const wchar_t* lpcwsz)
  51. {
  52. // 在UNICODE版本中, 选用wprintf函数来显示UNICODE字符串,
  53. // 选用wcslen函数来测量字符串长度
  54. wprintf(L"/n(W)字符串 %s 长度为%d", lpcwsz, wcslen(lpcwsz));
  55. }
  56. // 下面这一组编译器指令, 根据是否定义UNICODE(或_UNICODE)宏, 映射不同的函数
  57. // 可以删除#if和#endif之间的代码, 查看运行结果的变化, 思考产生这种变化的原因
  58. #if defined(UNICODE) | defined(_UNICODE)
  59. // 定义ShowCharacter宏映射到ShowCharacterW函数
  60. #define ShowCharacter ShowCharacterW
  61. // 定义ShowString宏映射到ShowStringW函数
  62. #define ShowString ShowStringW
  63. #else
  64. // 定义ShowCharacter宏映射到ShowCharacterA函数
  65. #define ShowCharacter ShowCharacterA
  66. // 定义ShowString宏映射到ShowStringA函数
  67. #define ShowString ShowStringA
  68. #endif
  69. // 定义缓冲区长度为512个字符
  70. #define BUF_LEN 512
  71. int _tmain(int argc, TCHAR* argv[])
  72. {
  73. // 定义变量, 保存字符
  74. TCHAR c = _T('A');
  75. // 定义字符数组, 保存字符串
  76. TCHAR szStr[] = _T("ABC大家好");
  77. // 定义指向字符串的指针
  78. TCHAR* lpszStr = _T("Hello你好");
  79. // 定义指向字符串的常量指针
  80. const TCHAR* lpcszStr = _T("GoodBye再见");
  81. int bSame;
  82. // 定义BUF_LEN长度的字符数组作为缓冲区
  83. TCHAR szBuffer[BUF_LEN] = _T("");
  84. // 定义ASCII字符集缓冲区
  85. char szBufferA[BUF_LEN] = "";
  86. // 定义UNICODE字符集缓冲区
  87. wchar_t szBufferW[BUF_LEN] = L"";
  88. // 定义错误代码22
  89. const int nError = 22;
  90. // 设置语言环境为中文
  91. _tsetlocale(LC_ALL, _T("zhi"));
  92. // 调用ShowCharacter宏
  93. ShowCharacter(c);
  94. // 调用ShowCharacter宏
  95. ShowString(szStr);
  96. ShowString(lpszStr);
  97. ShowString(lpcszStr);
  98. // _tcsicmp是tchar.h中定义的宏,
  99. // 在不同的字符集环境下映射为stricmp或wcsicmp函数
  100. bSame = _tcsicmp(lpszStr, lpcszStr);
  101. if (bSame == 0)
  102. {
  103. // _tprintf是tchar.h中定义的宏, 在不同字符集环境下映射为printf或wprintf函数
  104. _tprintf(_T("/n字符串 %s 与 %s 相同"), lpszStr, lpcszStr);
  105. }
  106. else
  107. _tprintf(_T("/n字符串 %s 与 %s 不同"), lpszStr, lpcszStr);
  108. // _tcscpy_s是tchar.h中定义的宏,
  109. // 在不同字符集环境下映射为strcpy_s或wcscpy_s函数(_s表示安全版本函数)
  110. _tcscpy_s(szBuffer, BUF_LEN, lpszStr);
  111. // _tcscat_s是tchar.h中定义的宏,
  112. // 在不同字符集环境下映射为strcat_s或wcscat_s函数(_s表示安全版本函数)
  113. _tcscat_s(szBuffer, BUF_LEN, lpcszStr);
  114. // _tcslen是tchar.h中定义的宏,
  115. // 在不同字符集环境下映射为strlen或wcslen函数
  116. _tprintf(_T("/n字符串 %s 长度为 %d"), szBuffer, _tcslen(szBuffer));
  117. // 接下来, 我们看一下FormatMessage函数在不同环境下的应用
  118. // ASCII环境下应用, 第5个参数使用char类型数组作为缓冲
  119. FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, nError, 0, szBufferA, BUF_LEN, NULL);
  120. printf("/n错误信息:%s", szBufferA);
  121. // UNICODE环境下应用, 第5个参数使用wchar_t类型数组作为缓冲
  122. FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, nError, 0, szBufferW, BUF_LEN, NULL);
  123. wprintf(L"错误信息:%s", szBufferW);
  124. // 自适应环境, 第5个参数使用TCHAR类型数组作为缓冲
  125. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, nError, 0, szBuffer, BUF_LEN, NULL);
  126. _tprintf(_T("错误信息:%s"), szBuffer);
  127. _tprintf(_T("/n"));
  128. system("pause");
  129. return 0;
  130. }

免责声明:文章转载自《TCHAR数据类型介绍》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇认识Windows Communication FoundationPandas建立空的dataframe和cumsum累加函数下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

golang 高效字符串拼接

https://blog.csdn.net/u012210379/article/details/45110705 虽然方便,但是使用+=操作符并不是在一个循环中往字符串末尾追加字符串最有效的方式,一个有效的方式是准备好一个字符串切片([]string),然后使用strings.Join()函数一次性将所有字符串串联起来。但是在go中还有一个更好的方法,其...

mysql 判断null 和 空字符串

mysql 判断null 和 空字符串 1.在mysql中null 不能使用任何运算符与其他字段或者变量(函数、存储过程)进行运算。若使用运算数据就可能会有问题。 2.对null 的判断: 创建一个user表:id 主健 name 可以为空 select * from user; insert into user values('33',null); #...

oracle instr查询字符串

INSTR   (源字符串, 目标字符串, 起始位置, 匹配序号)   在Oracle/PLSQL中,instr函数返回要截取的字符串在源字符串中的位置。只检索一次,就是说从字符的开始   到字符的结尾就结束。   语法如下:   instr( string1, string2 [, start_position [, nth_appearance ] ]...

oracle字符集的查看和修改

一、什么是Oracle字符集 Oracle字符集是一个字节数据的解释的符号集合,有大小之分,有相互的包容关系。ORACLE支持国家语言的体系结构允许你使用本地化语言来存储,处理,检索数据。它使数据库工具,错误消息,排序次序,日期,时间,货币,数字,和日历自动适应本地化语言和平台。 影响Oracle数据库字符集最重要的参数是NLS_LANG参数。 它的格式如...

python编码及requests乱码问题

1.字符编码简介 1.1. ASCIIASCII(American Standard Code for Information Interchange),是一种单字节的编码。计算机世界里一开始只有英文,而单字节可以表示256个不同的字符,可以表示所有的英文字符和许多的控制符号。不过ASCII只用到了其中的一半(x80以下),这也是MBCS得以实现的基础。...

构建安全的数据访问配置管理(六)

数据库连接字符串是针对数据访问代码主要考虑的配置管理问题。应认真考虑这些字符串的存储位置以及如何保护它们(特别是当它们包括凭据时)。要提高加密管理安全性: •使用 Windows 身份验证。 •确保连接字符串的安全。 •使用受限制的 ACL 确保 UDL 文件的安全。 使用 Window 身份验证 使用 Windows 身份验证时,系统会为您管理凭据,而且...