_T、_TEXT、L、wchar、wstring、wcsncpy、wsprintf等用途

_T、_TEXT、L、wchar、wstring、wcsncpy、wsprintf等用途

#include "stdafx.h"
#include <iostream>
#include <string.h>
#include <string>
using namespace std;

#if 0

1._T的作用:

_T是一个宏,作用是让你的程序支持Unicode编码。
因为Windows使用两种字符集ANSI(使用""包裹)和UNICODE(使用L""包裹),
前者就是通常使用的单字节方式,
但这种方式处理像中文这样的双字节字符不方便,
容易出现半个汉字的情况。
而后者是双字节方式,方便处理双字节字符。

_T("")是一个宏,定义于tchar.h下。
#define __T(x) L ## x
#define _T(x) __T(x)

如果你编译一个程序为ANSI方式,_T实际不起任何作用。
而如果编译一个程序为UNICODE方式,则编译器会把"Hello"字符串
以UNICODE方式保存。_T和_L的区别在于,_L不管你是以什么方式编译,一律以UNICODE方式保存
L是表示字符串资源为Unicode的。
比如
wchar_tStr[] = L"Hello World!";
这个就是双字节存储字符了

char大小为一个字节,有8位,也就是8个二进制位,所以可以表示的字符数量为2的8次幂为256个字符,
但有些语言仅仅用256个字符表达不完,所以采用新的类型来存储,例如wchar_t

_T是一个适配的宏
当#ifdef _UNICODE的时候,_T就是L
没有#ifdef _UNICODE的时候,_T就是ANSI的。
比如:
LPTSTR lpStr = new TCHAR[32];
TCHAR* szBuf = _T("Hello");
以上两句使得无论是在UNICODE编译条件下还是在ANSI编译条件下都是正确编译的。

尽量使用这种表示中间类型的语法,它可以根据需要适应不同的类型,而不需要再次修改,如_tcslen


2.TEXT, _TEXT 和_T 一样的

如下面三语句:
TCHAR szStr1[] = TEXT("str1");
char szStr2[] = "str2";
WCHAR szStr3[] = L("str3");

那么第一句话在定义了UNICODE时会解释为第三句话,没有定义时就等于第二句话。
但第二句话无论是否定义了UNICODE都是生成一个ANSI字符串,而第三句话总是生成UNICODE字符串。
为了程序的可移植性,建议都用第一种表示方法。但在某些情况下,某个字符必须为ANSI或UNICODE,那就用后两种方法


3.在字符串前加一个L作用:

如 L"我的字符串" 表示将ANSI字符串转换成unicode的字符串,就是每个字符占用两个字节。
cout << sizeof("asd") << endl;  //输出4
cout << sizeof(L"asd") << endl; //输出8
因为字符串中有\0的存在,相应的值要比字面的值要大

4.TCHAR:
当没有定义_UNICODE宏时,TCHAR = char,_tcslen = strlen
当定义了_UNICODE宏时,TCHAR = wchar_t , _tcslen = wcslen
当我们定义了UNICODE宏,就相当于告诉了编译器:我准备采用UNICODE版本。
这个时候,TCHAR就会摇身一变,变成了wchar_t。而未定义UNICODE宏时,TCHAR摇身一变,
变成了unsignedchar。这样就可以很好的切换宽窄字符集


5.wstring

typedef basic_string <wchar_t> wstring;
std::wstring
宽字符的字符串类
这是basic_string类模板的实例化,它使用wchar_t作为字符类型,
使用其默认的char_traits和allocator类型

std::wstring主要用于 UTF - 16编码的字符, 而std::string主要用于存储单字节的字符(ASCII字符集),
但是也可以用来保存UTF - 8编码的字符。(UTF - 8和UTF - 16是UNICODE字符集的两种不同的字符编码)

如果你的程序支持多种语言,那么使用UTF - 16来处理字符会方便一些,因为该编码中的每个字符都占用2个字节;
而UTF - 8中的字符所占的字节可能是1个字节或者多个字节(范围是1 ~6 个字节),多字节的字符编码对于处理字符不方便,
而且std::string也没有提供对UTF - 8的支持

例:
#include <iostream>
#include <string>
using namespace std;

int main()
{
	string text1 = "你好,世界";
	wstring text2 = L"你好,世界";
	cout << text1.length() << endl;  //输出10
	cout << text2.length() << endl;  //输出5
	system("pause");
}

6.wcsncpy

wchar_t * wcsncpy(wchar_t * destination,const wchar_t * source,size_t num);

从宽字符串复制字符:
将源的前num个字符复制到目标。如果在复制num个字符之前找到源 C宽字符串的末尾(由空宽字符表示),
则使用其他空宽字符填充目标,直到已向其写入总共num个字符。 没有空宽字符是在结束隐含所附目的地
如果源长于NUM(因此,在这种情况下,目的地可能不是空终止的C宽字符串)。
目的地和来源不应重叠(重叠时请参阅wmemove以获得更安全的替代方案)。
这是strncpy(<cstring>)的宽字符等价物

例:
#include "stdafx.h"
#include <iostream>
#include <wchar.h>
using namespace std;

int main()
{
	wchar_t wcs1[] = L"To be or not to be";
	wchar_t wcs2[40];
	wchar_t wcs3[40];

	wcsncpy(wcs2, wcs1, 40);
	wprintf(L"%ls\n", wcs2);

	wcsncpy(wcs3, wcs2, 5);
	wprintf(L"%ls\n", wcs3);

	wcs3[5] = L'\0';
	wprintf(L"%ls\n", wcs3);

	return 0;
}

7.wsprintf

头文件为:windows.h

函数作用:
函数wsprintf()将一系列的字符和数值输入到缓冲区。
输出缓冲区里的的值取决于格式说明符(即"%")。
如果写入的是文字,此函数给写入的文字的末尾追加一个'\0'。
函数的返回值是写入的长度,但不包括最后的'\0'。

函数声明: 
int __cdecl wsprintf(
	_Out_ LPTSTR lpOut,  //输出缓冲区
	_In_ LPCTSTR lpFmt,	 //格式字符串
	_In_...);

参数
lpOut[out]  类型:LPTSTR    接收缓冲区格式化输出.缓冲区最大为 1024 bytes.
lpFmt[in]   类型:LPCTSTR   控制输出的格式.
...[in]
可变参数

%d 格式化为十进制有符号整数输出到缓冲区
%u 格式化为十进制无符号整数输出到缓冲区
%s 格式化为字符串输出到缓冲区
%c 格式化为单个字符输出到缓冲区
%e 格式化为指数形式的浮点数输出到缓冲区
%x 格式化为无符号以十六进制表示的整数(a - f小写输出)输出到缓冲区
%X 格式化为无符号以十六进制表示的整数(a - f大写输出)输出到缓冲区
% 0 格式化为无符号以八进制表示的整数输出到缓冲区
%g 格式化为自动选择合适的表示法输出到缓冲区

例:
#include "stdafx.h"
#include <iostream>
//这俩个头文件的顺序不能颠倒
//否则会出现#error "No Target Architecture"的错误
#include <windows.h>
#include <WinNT.h>

using namespace std;

int main()
{
	int x = 6;
	LPTSTR szBuffer = new TCHAR[1024]; //LPTSTR的头文件:WinNT.h
	wsprintf(szBuffer, "%d", x);  
	wprintf(L"%ls\n", szBuffer);
	return 0;
}

#endif

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值