zoukankan      html  css  js  c++  java
  • 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符号。

    1.  
      // 定义宏UNICODE和_UNICODE, 一旦定义了该宏, C语言编译器将在UNICODE环境下工作
    2.  
      // 注意, 一般情况下需要定义UNICODE宏和_UNICODE宏, 因为不同版本的C编译器要求不同
    3.  
       
    4.  
      // 在正式工作时, 并不需要定义这两个宏, 只需要在"项目属性->配置属性->字符集"中选择
    5.  
      // UNICODE字符集或是多字节字符集即可, 开发环境会自动定义相应的宏
    6.  
      #if !defined(UNICODE)
    7.  
      #define UNICODE
    8.  
      #endif
    9.  
       
    10.  
      #if !defined(_UNICODE)
    11.  
      #define _UNICODE
    12.  
      #endif
    13.  
       
    14.  
      // 在所有头文件之前包含tchar.h头文件
    15.  
      // 这是程序可以应用各类替代宏的基础
    16.  
      #include <tchar.h>
    17.  
      #include <locale.h>
    18.  
      #include <stdio.h>
    19.  
      #include <stdlib.h>
    20.  
      #include <windows.h>
    21.  
       
    22.  
      /**
    23.  
      * 显示一个字符, ASCII版本
    24.  
      * 参数:c, 要显示的字符变量
    25.  
      */
    26.  
      void ShowCharacterA(char c)
    27.  
      {
    28.  
      // 在ASCII版本中, 选用printf函数来显示字符串
    29.  
      printf("(A)字符 %c 占据空间 %d", c, sizeof(c));
    30.  
      }
    31.  
       
    32.  
      /**
    33.  
      * 显示一个字符, UNICODE版本
    34.  
      * 参数:c, 要显示的字符变量
    35.  
      */
    36.  
      void ShowCharacterW(wchar_t wc)
    37.  
      {
    38.  
      // 在UNICODE版本中, 选用wprintf函数来显示UNICODE字符串
    39.  
      wprintf(L"(W)字符 %c 占据空间 %d", wc, sizeof(wc));
    40.  
      }
    41.  
       
    42.  
      /**
    43.  
      * 显示一个字符串, ASCII版本
    44.  
      * 参数:lpcsz, 要显示的字符变量
    45.  
      */
    46.  
      void ShowStringA(const char* lpcsz)
    47.  
      {
    48.  
      // 在ASCII版本中, 选用printf函数来显示ASCII字符串,
    49.  
      // 选用strlen函数来测量字符串长度
    50.  
      printf("/n(A)字符串 %s 长度为%d", lpcsz, strlen(lpcsz));
    51.  
      }
    52.  
       
    53.  
      /**
    54.  
      * 显示一个字符串, UNICODE版本
    55.  
      * 参数:lpcwsz, 要显示的字符变量
    56.  
      */
    57.  
      void ShowStringW(const wchar_t* lpcwsz)
    58.  
      {
    59.  
      // 在UNICODE版本中, 选用wprintf函数来显示UNICODE字符串,
    60.  
      // 选用wcslen函数来测量字符串长度
    61.  
      wprintf(L"/n(W)字符串 %s 长度为%d", lpcwsz, wcslen(lpcwsz));
    62.  
      }
    63.  
       
    64.  
       
    65.  
       
    66.  
       
    67.  
      // 下面这一组编译器指令, 根据是否定义UNICODE(或_UNICODE)宏, 映射不同的函数
    68.  
      // 可以删除#if和#endif之间的代码, 查看运行结果的变化, 思考产生这种变化的原因
    69.  
      #if defined(UNICODE) | defined(_UNICODE)
    70.  
       
    71.  
      // 定义ShowCharacter宏映射到ShowCharacterW函数
    72.  
      #define ShowCharacter ShowCharacterW
    73.  
       
    74.  
      // 定义ShowString宏映射到ShowStringW函数
    75.  
      #define ShowString ShowStringW
    76.  
       
    77.  
      #else
    78.  
       
    79.  
      // 定义ShowCharacter宏映射到ShowCharacterA函数
    80.  
      #define ShowCharacter ShowCharacterA
    81.  
       
    82.  
      // 定义ShowString宏映射到ShowStringA函数
    83.  
      #define ShowString ShowStringA
    84.  
       
    85.  
      #endif
    86.  
       
    87.  
       
    88.  
       
    89.  
      // 定义缓冲区长度为512个字符
    90.  
      #define BUF_LEN 512
    91.  
       
    92.  
      int _tmain(int argc, TCHAR* argv[])
    93.  
      {
    94.  
      // 定义变量, 保存字符
    95.  
      TCHAR c = _T('A');
    96.  
       
    97.  
      // 定义字符数组, 保存字符串
    98.  
      TCHAR szStr[] = _T("ABC大家好");
    99.  
       
    100.  
      // 定义指向字符串的指针
    101.  
      TCHAR* lpszStr = _T("Hello你好");
    102.  
       
    103.  
      // 定义指向字符串的常量指针
    104.  
      const TCHAR* lpcszStr = _T("GoodBye再见");
    105.  
       
    106.  
      int bSame;
    107.  
       
    108.  
      // 定义BUF_LEN长度的字符数组作为缓冲区
    109.  
      TCHAR szBuffer[BUF_LEN] = _T("");
    110.  
       
    111.  
      // 定义ASCII字符集缓冲区
    112.  
      char szBufferA[BUF_LEN] = "";
    113.  
       
    114.  
      // 定义UNICODE字符集缓冲区
    115.  
      wchar_t szBufferW[BUF_LEN] = L"";
    116.  
       
    117.  
      // 定义错误代码22
    118.  
      const int nError = 22;
    119.  
       
    120.  
      // 设置语言环境为中文
    121.  
      _tsetlocale(LC_ALL, _T("zhi"));
    122.  
       
    123.  
      // 调用ShowCharacter宏
    124.  
      ShowCharacter(c);
    125.  
       
    126.  
      // 调用ShowCharacter宏
    127.  
      ShowString(szStr);
    128.  
      ShowString(lpszStr);
    129.  
      ShowString(lpcszStr);
    130.  
       
    131.  
      // _tcsicmp是tchar.h中定义的宏,
    132.  
      // 在不同的字符集环境下映射为stricmp或wcsicmp函数
    133.  
      bSame = _tcsicmp(lpszStr, lpcszStr);
    134.  
       
    135.  
      if (bSame == 0)
    136.  
      {
    137.  
      // _tprintf是tchar.h中定义的宏, 在不同字符集环境下映射为printf或wprintf函数
    138.  
      _tprintf(_T("/n字符串 %s 与 %s 相同"), lpszStr, lpcszStr);
    139.  
      }
    140.  
      else
    141.  
      _tprintf(_T("/n字符串 %s 与 %s 不同"), lpszStr, lpcszStr);
    142.  
       
    143.  
      // _tcscpy_s是tchar.h中定义的宏,
    144.  
      // 在不同字符集环境下映射为strcpy_s或wcscpy_s函数(_s表示安全版本函数)
    145.  
      _tcscpy_s(szBuffer, BUF_LEN, lpszStr);
    146.  
       
    147.  
      // _tcscat_s是tchar.h中定义的宏,
    148.  
      // 在不同字符集环境下映射为strcat_s或wcscat_s函数(_s表示安全版本函数)
    149.  
      _tcscat_s(szBuffer, BUF_LEN, lpcszStr);
    150.  
       
    151.  
      // _tcslen是tchar.h中定义的宏,
    152.  
      // 在不同字符集环境下映射为strlen或wcslen函数
    153.  
      _tprintf(_T("/n字符串 %s 长度为 %d"), szBuffer, _tcslen(szBuffer));
    154.  
       
    155.  
      // 接下来, 我们看一下FormatMessage函数在不同环境下的应用
    156.  
       
    157.  
      // ASCII环境下应用, 第5个参数使用char类型数组作为缓冲
    158.  
      FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, nError, 0, szBufferA, BUF_LEN, NULL);
    159.  
      printf("/n错误信息:%s", szBufferA);
    160.  
       
    161.  
      // UNICODE环境下应用, 第5个参数使用wchar_t类型数组作为缓冲
    162.  
      FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, nError, 0, szBufferW, BUF_LEN, NULL);
    163.  
      wprintf(L"错误信息:%s", szBufferW);
    164.  
       
    165.  
      // 自适应环境, 第5个参数使用TCHAR类型数组作为缓冲
    166.  
      FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, nError, 0, szBuffer, BUF_LEN, NULL);
    167.  
      _tprintf(_T("错误信息:%s"), szBuffer);
    168.  
       
    169.  
      _tprintf(_T("/n"));
    170.  
      system("pause");
    171.  
      return 0;
    172.  
      }
  • 相关阅读:
    android之自定义ViewGroup和自动换行的布局的实现
    早上开发有感:事情原本可以变的简单
    android中textview显示汉字,字母,数字乱行行问题解决
    MeasureSpec介绍及使用详解
    android中status bar 小结
    Android推送方式比较(转)
    error: Entry 'xxxxxx' not uptodate. Cannot merge.
    android2.3:加载你的SD卡与can't mount /dev/block/mmcblk0
    有客户自远方来,不亦乐乎?唉,怎一个愁字了得
    卸载Norton 8企业版的一次经历
  • 原文地址:https://www.cnblogs.com/MCSFX/p/13715015.html
Copyright © 2011-2022 走看看