关于字符,程序员需要知道的东西

本文详细介绍了Win32编程环境下各种字符串类型及其转换方法,包括ANSI、Unicode和MBCS等不同字符集的处理方式。文章还讨论了各种类型指针的区别以及如何在不同的字符集中正确地表示和转换字符串。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

以下文字总结于网路和书籍。


1. 说说那些乱七八糟的类型名

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

P表示这是一个指针。

T表示_T宏,这个宏用来表示你的字符是否使用UNICODE,

如果你的程序定义了UNICODE或者其他相关的宏,那么这个字符或者字符串将被作为UNICODE字符串,否则就是标准的ANSI字符串。

STR表示这个变量是一个字符串。

C表示是一个常量,const。

LPTSTR: 如果定义了UNICODE宏则LPTSTR被定义为LPWSTR。typedef LPTSTR LPWSTR;

否则LPTSTR被定义为LPSTR。 typedef LPTSTR LPSTR;

 

下面列出一些常用的typedefs:

类型       MBCS     Unicode

WCHAR     wchar_t    wchar_t

LPSTR       char*     char*

LPCSTR     const char*  const char*

LPWSTR         wchar_t*    wchar_t*

LPCWSTR    const wchar_t* const wchar_t*

TCHAR         char         wchar_t

LPTSTR       TCHAR*(或char*) TCHAR* (或wchar_t*)

LPCTSTR   const TCHAR*   const TCHAR*

由于Win32 API文档的函数列表使用函数的常用名字(例如, SetWindowText"),所有的字符串都是用TCHAR来定义的。(除了XP中引入的只适用于Unicode的API)。

LPTSTR:LPSTR、LPWSTR两者二选一,取决于是否宏定义了UNICODE或ANSI。

LPCTSTR: LPCSTR、LPCWSTR两者二选一,取决于是否宏定义了UNICODE或ANSI。

TCHAR:wchar_t 、char两者二选一,取决于是否宏定义了UNICODE或ANSI。

#ifdef UNICODE

    typedef LPWSTR LPTSTR;

    typedef LPCWSTR LPCTSTR;

    typedef TCHAR wchar_t;

#else

    typedef LPSTR LPTSTR;

    typedef LPCSTR LPCTSTR;

    typedef TCHAR char;

#endif

另外CString = LPCTSTR


2. 各个数据类型的函数库

  字符集                     特性                                                    实例   

  ANSI                       操作函数function以str开头                     strcpy   

  Unicode                  操作函数function以wcs开头                    wcscpy   

  MBCS                     操作函数function以_mbs开头                 _mbscpy   

  ANSI/Unicode          操作函数function以_tcs开头                   _tcscpy(C运行期库)   

  ANSI/Unicode          操作函数function以lstr开头                     lstrcpy(Windows函数function)   

  所有新的及未过时的函数function都同时拥有ANSI及Unicode两个版本。ANSI版本函数function结尾以A表示;Unicode版本函数function结尾以W表示。Windows如下定义设置:   

  #ifdef     UNICODE   

  #define     CreateWindowEx     CreateWindowExW   

  #else   

  #define     CreateWindowEx     CreateWindowExA   

  #endif       //   !UNICODE


3. 如何表示字符串常量?   

  字符集                  实例   

  ANSI                    “string”   

  Unicode                L“string”   

  ANSI/Unicode        T(“string”)或_TEXT(“string”)或TEXT(“string”)


4. 各个类型之间的相互转换

4.1 短到长

LPSTR to LPTSTR:_T() (别名还有 _TEXT(), TEXT()),如“Hello”转换成_T("Hello")。使用L不大好,但是如果只使用了Unicode也可以用。

LPSTR to LPWSTR:可以使用L,如L"Hello"。也可以使用使用_T()。

4.2 CString到WCHAR*或者char*

4.2.1 CString和WCHAR*(wchar_t*)的转化

方法一:使用wcscpy()函数

1CString str("string");
2WCHAR pWchar[100];
3wcscpy(pWchar,str);

方法二:使用wcscpy_s()函数

这个函数是上一个函数的安全版本,调用上一个函数如果pWchar的内存不足时,容易引发意味的错误,但是wcscpy_s()则不会,应该其内存大小已经指定出来了:

1CString str("string");
2WCHAR pWchar[100];
3wcscpy_s(pWchar,100,str);

方法三:使用_tcscpy()函数

1CString str("string");
2WCHAR pStr[100];
3_tcscpy(pStr,str);

方法四:使用_tcscpy_s()函数

同wcscpy_s()一样,_tcscpy_s()函数也是_tcscpy()函数的安全版本:

1CString str("string");
2WCHAR pStr[100];
3_tcscpy_s(pStr,100,str);


4.2.2 CString和char*的转化

方法一:使用wcstombs()函数

1CString str("string");
2char pChar[100];
3wcstombs(pChar,str,100);

方法二:使用wcstombs_s()函数

同上面一样,wcstombs_s()是wcstombs()的安全版本:



所以结论,为提高可移植性,定义字符串时用TCHAR、LPCTSTR和LPTSTR,转化为UNICODE时用_T而不用L。


后记:说说char~

char 虽然被称为短整形,但是char并不像int short long那样默认是signed。char的符号取决于编译器,而不是取决于C语言本身。

char的范围0~127,unsigned char的范围是0~255,signed char的范围是-127~127。char所有的值总是会同时落在signed char和unsigned char中。char的取值范围正好是signed char和unsigned char的交集。

做一个编译器的例子看看,代码如下。编译器VS2010的CMD,编译命令CL(CL.exe)。

cl xxx.c 运行结果是 ‘-1’ = -1;

cl /J xxx.c运行结果是'-1' = 255;/J是宏定义Unsigned的意思。

由此可见VS默认是signed char = char,后来设置参数又有了char = unsigned char.

由此证明char的signed还是unsigned不是c语言里的内容,取决于编译器。


#include <stdio.h>

int main(void)
{
	char pear = -1;
	
	printf("'-1'= %d\n", pear);
	
	getchar();
	return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值