TCHAR,WCHAR,LPSTR,LPWSTR,LPCSTR的区别

多字节字符集与Unicode字符集(CString char*和wchar_t* 容易出错的原因) 1.基本概念 2.L与_T 3.char TCHAR 与 wchar_t,strcpy wcscpy与_tcscpy 4.LPSTR,LPCSTR,LPTSTR,LPCTSTR,LPWSTR,LPCWSTR 5.ANSI转Unicode(char 转 wchar_t) 6.Unicode转ANSI(wchar_t 转 har) 7.CString 1.ANSI与Unicode ANSI:多字... 阅读详情

            在C++的窗口应用程序开发过程中,我们经常对TCHAR,LPCTSTR这样的关键字迷惑。接下来将详细解释他们之间的区别。
          通常,一个字符可以用1个字节或两个字节来表示。1个字节的字符为ANSI编码字符,通常所有的英文字符都采用ANSI编码。2个字节的字符为Unicode编码,可以表示世界上所有的语言。

          在VC++编译器中,分别用char和wchar_t数据类型来标志ANSI和Unicode编码的字符。为了理解方便,我们可以认为两字节字符是Windows操作系统用例支持多语言的方法。Microsoft Windows用UTF-16字符编码来代表2字节编码。怎么样能让你的C/C++代码不依赖于具体的字符编码呢?

建议1:用一般的数据类型和名字代表字符和字符串

 例如:char cResponse; // 'Y' or 'N'

char sUsername[64];

用下面的方式来替代:

wchar_t cResponse; // 'Y' or 'N'

wchar_t sUsername[64];

为了支持多语言(Unicode),可以用下面的方式:

#include<TCHAR.H> // Implicit or explicit include

TCHAR cResponse; // 'Y' or 'N'

TCHAR sUsername[64];//字符串

在项目设置中,选择配置选项卡的常规,然后选择字符集。选择使用Unicode字符集。

设置好了以后,当你的项目用该字符集编译时,TCHAR会被翻译成wchar_t.当用ANSI/MBCS编译,则翻译成char。你可以通过项目设置很方便的使用char和wchar_t,不会受到关键字的影响。

 

TCHAR的定义如下:

#ifdef_UNICODE

typedef wchar_t TCHAR;

#else

typedef char TCHAR;

#endif

当你设置字符集为“使用Unicode字符集”时,宏_UNICODE就已经定义,这时候TCHAR代表wchar_t,当字符集设置为“使用多字节字符集”时,TCHAR代表char。

与此类似,为了让单个函数支持多种字符集或多种语言,应该使用特殊的函数(宏)。

可以使用_tcscpy,_tcslen,_tcscat函数代替strcpy,strlen,strcat(包括后缀为_s的函数)和wcscpy,wcslen,wcscat。

 

   strlen的原型如下:

size_t strlen(const char*);

wcslen的原型如下:

size_t wcslen(const wchar_t* );

使用_tcslen的原型如下:

size_t _tcslen(const TCHAR* );

 

WC是为宽字符而设计的,因此wcs表示宽字符串。_tcs表示_T字符集串。_T可能代表char或者wchar_T。但是实际上,_tcslen(或其他的_tcs开头的函数)并不是函数,它们是宏。他们的定义如下:

#ifdef _UNICODE

#define _tcslen wcslen

#else

#define _tcslen strlen

#endif

该宏定义在头文件TCHAR.h中。

大家可能会问为什么它们定义成宏而不是函数?原因很简单,一个库或DLL可能导出与之相同的函数原型,忽略C++的重载。如下,你可能会导出如下函数:

void _TPrintChar(char);

客户端怎么按意图调用它呢?

void _TPrintChar(wchar_t);

_TPrintChar函数不能将该函数的参数变成2字节字符集,可能使用两个函数:

void PrintCharA(char); // A = ANSI

void PrintCharW(wchar_t);//W=wide character

可以简单地使用宏来定义,如下:

#ifdef _UNICODE

void _TPrintChar(wchar_t);

#else

void _TPrintChar(char);

#endif

客户端可以简单的调用:

TCHAR cChar;

_TPrintChar(cChar);

宏可以帮助我们很方便的使用ANSI或Unicode函数,为了方便,可以使用宏来定义SetWindowText函数:

// WinUser.H

#ifdef UNICODE

#define SetWindowText SetWindowTextW

#else

#define SetWindowText SetWindowTextA

#endif //!UNICODE

 

ANSI字符集:"This is ANSI String. Each letter takes 1 byte."每个字符占一个字节,不是Unicode编码,为了代表Unicode字符串,可以用前缀L,如下:

L"This is Unicode string. Each letter would take 2 bytes, including spaces."

在字符串前面的L表示把该字符串转换为Unicode字符串。转换后的字符串的源字符串长度的两倍。

你可以使用下面的方式来判断使用具体的字符集:

"ANSI String"; // ANSI

L"Unicode String"; // Unicode

 

_T("Either string, depending on compilation"); // ANSI or Unicode

// or use TEXT macro, if you need more readability

对于ANSI字符串没有前缀,对于Unicode字符集采用L前缀,使用前缀_T或TEXT可以根据编译器的设置来确定字符集,_T和TEXT都是宏,定义如下:

// SIMPLIFIED

#ifdef _UNICODE

 #define _T(c) L##c

 #define TEXT(c) L##c

#else

 #define _T(c) c

 #define TEXT(c) c

#endif

符号##是标记运算符,当字符串通过该宏传递参数进去可以将_T("Unicode") intoL"Unicode",该标记符在C/C++中都存在。

但是不能使用该宏将一个变量(字符和字符串)转变成Unicode文本或non-Unicode文本。如下:

char c = 'C';

char str[16] = "CodeProject";

_T(c);

_T(str);

上面的代码将出现编译错误。_T(c)和_T(str)在ANSI编译模式下可以通过编译。

在Windows API中存在大量的以字符串和字符为参数的函数,如SetWindowTextA/W

BOOL SetWindowText(HWND, constTCHAR*);

SetWindowText是一个宏,根据编译环境的设置来决定。

BOOL SetWindowTextA(HWND, constchar*);

BOOL SetWindowTextW(HWND, const wchar_t*);

使用下面的方法获取该函数的地址是错误的:

HMODULE hDLLHandle;

FARPROC pFuncPtr;

 

hDLLHandle = LoadLibrary(L"user32.dll");

 

pFuncPtr = GetProcAddress(hDLLHandle, "SetWindowText");

//pFuncPtr 为空, 因为不存在名字为SetWindowText的函数。

对于User32.DLL,导出的函数是SetWindowTextA和SetWindowTextW,不是函数SetWindowText.

 

 

 

在.NET框架中,可以很方便的标志导出的函数:

[DllImport("user32.dll")]

extern public static int SetWindowText(IntPtr hWnd, string lpString);

 

同时存在另一个宏:WCHAR等同于wchar_t.

 

TCHAR是单个字符,我们可以定义TCHAR数组或字符指针:

// ANSI characters

foo_ansi(char*);

foo_ansi(const char*);

/*const*/ char* pString;

 

// Unicode/wide-string

foo_uni(WCHAR*);

wchar_t* foo_uni(const WCHAR*);

/*const*/ WCHAR* pString;

 

// Independent

foo_char(TCHAR*);

foo_char(const TCHAR*);

/*const*/ TCHAR* pString;

从上面可以看出,使用TCHAR是最好的选择。

我们知道strlen的两个版本:

size_t strlen(const char*);

size_t strlen(LPCSTR);

但是LPCSTR是通过typedef定义的。typedef const char* LPCSTR; 

LP:代表长指针    C:代表常量   STR:代表字符串

LPCSTR would mean (Long)Pointer to a Constant String.

 

 

对于strcpy:

LPSTR strcpy(LPSTR szTarget, LPCSTR szSource);

szTarget是LPSTR类型,定义如下:

typedef char* LPSTR;

上面的函数都是针对ANSI字符串集,如果要支持Unicode字符集,要计算宽字符的长度使用wcslen。

size_t nLength;

nLength = wcslen(L"Unicode");

 

wcslen的定义如下:

size_t wcslen(const wchar_t* szString); // Or WCHAR*

或者:size_t wcslen(LPCWSTR szString);

 

LPCWSTR的定义如下:

typedef const WCHAR* LPCWSTR;

LP:代表指针;C代表常数;WSTR:宽字符串

 

strlen,wcslen or_tcslen返回的是字符串字符的个数不是字节数。

 

一个具体的例子:

int main()

{

   TCHAR name[] = "Saturn";

   int nLen; // Or size_t

 

lLen = strlen(name);

}

上面的代码以ANSI字符集可以正常编译,此时TCHAR为char.当在Unicode字符集下编译会出现错误,应该改成:TCHAR name[] = _T("Saturn");

OpenWRT系统启动流程全解析:从procd到ubus的完整链路(附源码分析) 本文深入解析了OpenWRT系统从内核移交控制权到用户空间服务就绪的完整启动链路。核心聚焦于进程管理器procd与通信总线ubus的协同工作机制,通过源码分析揭示了状态机转换、服务注册与事件分发的内在逻辑,为系统定制、启动优化与故障调试提供了清晰指南。 阅读详情

相关推荐

MySQL表名大小写敏感问题终极解决:lower_case_table_names=1不生效的3个隐藏坑

本文深入剖析了MySQL表名大小写敏感问题中,设置lower_case_table_names=1参数不生效的三个核心原因。关键在于理解该参数只能在数据库初始化前设置,并需排查配置文件优先级与正确停止服务的顺序。文章提供了从Windows迁移到Linux的完整避坑指南与验证方法,帮助DBA和开发者彻底解决这一跨平台兼容性难题。

weixin_29229055的博客 391

LPCTSTR和CString的关系

类型理解   LPCTSTR类型:   L表示long指针 这是为了兼容Windows 3.1等16位操作系统遗留下来的,在win32中以及其他的32位操作系统中, long指针和near指针及far修饰符都是为了兼容的作用。没有实际意义。   P表示这是一个指针   C表示是一个常量   T表示在Win32环境中, 有一个_T宏   STR表示这个变量是一个字符...

weixin_34268843的博客 1110

别再手动画柜子了!用EPLAN导入STEP模型,5分钟搞定一个标准机柜

本文详细介绍了如何利用EPLAN Pro Panel的3D布局功能,快速将STEP模型转化为智能机柜宏,大幅提升电气工程设计效率。通过实战步骤解析,包括模型导入、智能解析、安装面定义及拼柜技巧,帮助工程师5分钟内完成标准机柜设计,避免传统手动建模的尺寸偏差问题。

weixin_26875109的博客 433

[c++] LPWSTR、LPCSTR、LPCWSTR浅析

LPCSTR是Win32和VC++所使用的一种字符串数据类型。LPCSTR被定义成是一个指向以'\0'结尾的常量字符的指针。 LPWSTR是wchar_t字符串 LPCWSTR是一个指向unicode编码字符串的32位指针,所指向字符串是wchar型,而不是char型。 LPSTR和LPWSTR是Win32和VC++所使用的一种字符串数据类型。LPSTR被定义成是一个指向以NULL(‘\0...

初阳-.-#的博客 4万+

16QAM调制解调仿真(matlab,详细介绍仿真方案的设计、结果及结论、完整代码及注释)

16QAM调制解调仿真目录一、仿真要求二、仿真方案详细设计三、仿真结果及结论四、仿真代码 一、仿真要求 1.用基带等效的方式仿真16-QAM在AWGN信道下的误码率和误比特率性能,并与理论值相比较; 2.高阶与低阶的性能比较。 二、仿真方案详细设计 三、仿真结果及结论 仿真结果 16QAM的星座点图 64QAM的星座点图 16QAM加噪声后的星座点图 64QAM加噪声后的星座点图 16-QAM载波调制信号在AWGN信道下的误比特率性能比较 结论:由图可知,16QAM的误符号率

mango 5万+

【ESP32】SPI SRAM memory test fail。External RAM failed memory test!

log日志报错如下:这两条报错信息表明外部 SPI SRAM(静态随机存取存储器)的内存测试失败。

weixin_56217406的博客 1024

LPCSTR和LPCWSTR分别是什么

LPCWSTR是一个指向常量宽字符的指针,即指向一个以null结尾的Unicode字符串的指针。“LP"代表"Long Pointer”,“C"代表"Constant”,“WSTR"代表"Wide String”。LPCSTR是一个指向常量字符的指针,即指向一个以null结尾的ASCII字符串的指针。“LP"代表"Long Pointer”,“C"代表"Constant”,“STR"代表"String”。LPCSTR和LPCWSTR都是Windows平台下的数据类型,用于表示指向字符串的指针。

巴拉巴拉变不出 1749

伪傻瓜式安装sql server2008【附带安装包】

安装各式各样的软件无疑是学习过程中…较…为烦躁的一部分 木有醋 但还是开始吧 为什么这是伪呢? 因为刚开始天真无邪的我真的是傻瓜式安装(迷之自信),结果就B了(打开配置管理器的瞬间….一片空白) BaiduCloud分享 红领巾在何方?? Link链接:https://pan.baidu.com/s/1NZCxP0Y27dBPrgHoRWLDyQ...

EuniBoom的博客 6万+

LPCTSTR是什么意思?

如何理解LPCTSTR, L表示long指针, 这是为了兼容Windows 3.1等16位操作系统遗留下来的, 在win32中以及其他的32为操作系统中, long指针和near指针及far修饰符都是为了兼容的作用。没有实际意义。P表示这是一个指针C表示是一个常量T在Win32环境中, 有一个_T宏, 这个宏用来表示你的字符是否使用UNICODE, 如果你的程序定义了UNICODE或者其他相关的宏

1770

GEE开发之ERA5(气温、降水、压力、风速等)数据获取和分析

前言:ERA5主要提供DAILY和MONTHLY两大类别数据,其中主要包括气温、降水、压力、风速等。

等待着冬天的风的博客 3万+

AI在电商中的搜索优化

自拟标题 《AI技术助力电商搜索优化:深度解析一线大厂面试题及算法编程实践》 概述 随着人工智能技术的不断发展,AI在电商搜索优化中的应用日益广泛。本文将围绕“AI在电商中的搜索优化”这一主题,介绍国内头部一线大厂如阿里巴巴、百度、腾讯、字节跳动等在面试中常见的AI相关面试题和算法编程题,并提供详尽的答案解

AI天才研究院 912

LPCTSTR,LPCSTR,LPTSTR,LPSTR的区别及用法

LPCSTR       32-bit   指针,指向一个常量字串   LPSTR          32-bit   指针,指向一个字串   LPCTSTR    32-bit   指针,指向一个常量字串。此字串可移植到Unicode   和DBCS   LPTSTR       32-bit   指针,指向一个字串。此字串可移植到Unicode   和DBCS ----------------

hank209的VC/MFC学习之旅 1943

《无线传感网络 matlab》:从入门到实践

这就是如何使用Matlab建立一个简单的无线传感网络并进行仿真的方法。当然,这只是一个入门级的示例,真正的无线传感网络可能会更加复杂和庞大。首先,我们需要创建一个无线传感网络的基础结构。接下来,我们需要定义一个数据包的格式,以便节点之间可以交换信息。无线传感网络是一种由无线传感器节点组成的、自组织的网络。现在,我们可以开始编写节点代码了。我们将使用Matlab提供的工具箱来构建一个简单的无线传感网络,并对其进行仿真和分析。现在,我们可以将这个节点复制9次,以创建一个包含10个节点的无线传感网络。

NoerrorCode的博客 296

WCHAR、 LPSTR、 LPCSTR、 LPWSTR、 LPCWSTR、 TCHAR、 LPTSTR、 LPTCSTR的区别

L表示long指针,这是为了兼容Windows 3.1等16位操作系统遗留下来的,在win32中以及其他的32为操作系统中, long指针和near指针及far修饰符都是为了兼容的作用,没有实际意义。即win32中,long,near,far指针与普通指针没有区别,LP与P是等效

uqapuqap的专栏 1804

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

ANSI,Unicode;char,wchar_t, TCHAR;LPSTR, LPWSTR总结

摘要: 本文总结对比了ANSI/Unicode,char/wchar_t,LPSTR/LPWSTR。 简单描述了char, wchar_t,  TCHAR的初始化,操作函数,输出的方法。 数据类型 操作 初始化 输出 WinLP ANSI char str(strcpy) "char" printf LPSTR Unicode wchar_t wcs(wcscpy) L"char" wprintf LPWSTR 通用 TCHAR _tcs(_tcscpy) _T("char") _tprintf

矩阵实验室 2129

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

PTCHAR、LPSTR、LPCSTR、PSTR等的区别

CHAR 存放单个字符 WCHAR         存放双字符 TCHAR 与WCHAR无异 PTCHAR 指向双字符类型字符串 LPSTR 一个32位的指向字符串的指针       LPCSTR    一个32位的指向字符串常量的指针       LPWSTR      一个32位的指向unicode字符串的指针       LPCWSTR   一个32

c914620529的博客 5581

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

TCHAR, WCHAR, LPSTR, LPWSTR, LPCTSTR<三>

TCHAR, WCHAR, LPSTR, LPWSTR, LPCTSTR究竟是神马!!!

FightForProgrammer的专栏 1243

CString与LPCWSTR、LPSTR、char*、LPWSTR等类型的转换【转】

CString与PLCWSTR,PLSTR, CHAR 存放单个字符 WCHAR 存放双字符 TCHAR 与WCHAR无异 PTCHAR 指向双字符类型字符串 LPSTR 一个32位的指向字符串的指针 LPCSTR 一个32位的指向字符串常量的指针 LPWSTR 一个32位的指向unicode字符串的指针 LPCWSTR 一个32位的指向unicode字符串常量的指针 PSTR 指向字符串的指针,poionter string 注: 很多变量前加lpsz,l

fwsylin的博客 2136

C++中字符三兄弟(WCHAR、CHAR、TCHAR)

前言 众所周知,C++中的字符分成两种类型:wchar_t和char。其中,WCHAR 对应 wchar_t,CHAR 对应 char,TCHAR 是一种条件编译的类型,根据条件动态代表 wchar_t 或者 char。 一、与字符集的关系 其实,它们三者和对应的字符集相关。C语言用 char 来表示一个8位 ANSI 字符,用wchar_t表示一个16位的Unicode字符。strlen返回一个ANSI字符串的长度,wcslen返回一个Unicode字符串的长度。 其中,ANSI 是单字节字符集,

liuzhen007的专栏 9566

LPSTR,LPCSTR,LPWSTR,LPCWSTR,LPTSTR,LPCTSTR,TCHAR...

首先char* 是指向ANSI字符数组的指针,其中每个字符占据8位(有效数据是除掉最高位的其他7位),这里保持了与传统的C,C++的兼容。 LP的含义是长指针(long pointer)。LPSTR是一个指向以'/0'结尾的ANSI字符数组的指针,与char*可以互换使用,在win32中较多地使用LPSTR。而LPCSTR中增加的'C'的含义是"CONSTANT"(常量),表明这种数据类型的实

Beyond.cn 1058

Dword、LPSTR、LPWSTR、LPCSTR、LPCWSTR、LPTSTR、LPCTSTR

L表示long指针,这是为了兼容Windows 3.1等16位操作系统遗留下来的,在win32中以及其他的32为操作系统中, long指针和near指针及far修饰符都是为了兼容的作用,没有实际意义。即win32中,long,near,far指针与普通指针没有区别,LP 与P是等效的。 P表示这是一个指针。 T表示_T宏,这个宏用来表示你的字符是否使用UNICODE, 如果你的程序定义了U...

weixin_30553837的博客 241

TCHAR,WCHAR,LPSTR,LPWSTR和LPCTSTR

转自:http://wuyuans.com/2012/09/tcharwcharlpstrlpwstr-and-lpctstr/ 从现在开始要进入嵌入式的开发了,复习一下c语言,先从基本的数据类型开始。TCHAR,WCHAR,LPSTR,LPWSTR和LPCTSTR,这几个看起来差不多,也很容易混淆,他们都是跟字符有密切关系的。要想知道他们的由来以及作用就必须先了解字符的编码。 0.字符编码

dreamgis的专栏 1138

LPSTR、LPCSTR、LPTSTR、LPCTSTR的来源及意义

UNICODE:它是用两个字节表示一个字符的方法。比如字符A在ASCII下面是一个字节,可A在UNICODE下面是两个字节,高字节用0填充,而且汉字程在ASCII下面是两个字节,而在UNICODE下仍旧是两个字节。UNICODE的用处就是定长表示世界文字,据统计,用两个字节可以编码现存的所有文字而没有二义。  LPSTR、LPCSTR、LPTSTR、LPCTSTR 及 LP

sanfengshou的专栏 1180

引用LPSTR、LPCSTR、LPTSTR、LPCTSTR、LPWSTR及LPCWSTR的意义及区别

1、ANSI(即MBCS):为多字节字符集,它是不定长表示世界文字的编码方式。ANSI表示英文字母时就和ASCII一样,但表示其他文字时就需要用多字节。 2、Unicode:用两个字节表示一个字符的编码方式。比如字符'A'在ASCII下面用一个字节表示,而在Unicode下面用两个字节表示,其中高字节用"0"填充;函数'程'在ASCII下面用两个字节表示,而在Unicode下面也是用两个字节表示。Unicode的用处就是定长表示世界文字,据统计,用两个字节可以编码现存的所有文字而没有二义。 3、W

十五年的一线软件设计师经验分享 548

【转自中华考试网】引用LPSTR、LPCSTR、LPTSTR、LPCTSTR、LPWSTR及LPCWSTR的意义及区别

1、ANSI(即MBCS):为多字节字符集,它是不定长表示世界文字的编码方式。ANSI表示英文字母时就和ASCII一样,但表示其他文字时就需要用多字节。 2、Unicode:用两个字节表示一个字符的编码方式。比如字符'A'在ASCII下面用一个字节表示,而在Unicode下面用两个字节表示,其中高字节用"0"填充;函数'程'在ASCII下面用两个字节表示,而在Unicode下面也是用两个字节表示

沐埜专栏 1092

CString 与 LPCWSTR、LPSTR、char*、LPWSTR 等类型的转换

From:https://www.cnblogs.com/leanee/articles/2940088.html char [] 到 LPWSTR转换的一个具体应用:http://www.cppblog.com/lateCpp/articles/153358.html CString详细讲解:https://blog.youkuaiyun.com/qq_41786318/article/detai...

freeking101的博客 3078
上一篇: MFC如何自定义消息与在线程中向主窗体控件发送数据
下一篇: 研究生期间有关语音识别方面资料的收集
xiaoding133
博客等级 码龄19年 415粉丝 159原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值