LPTSTR
已阅读 10 个网页
LPTSTR 是 Windows 编程中非常重要的一个数据类型,尤其在像 VC++ 6.0 这样的经典环境中非常常见。
简单来说,LPTSTR 是一个 指向字符串的长指针,但它的奇妙之处在于,它能根据你的项目设置(是否支持 Unicode)自动变身,让你的代码能更方便地在不同字符集之间移植。
1. LPTSTR 的“变身”原理
LPTSTR 的类型并不是固定不变的,它实际上是一个宏,它的真面目取决于你项目中是否定义了 UNICODE 宏。
-
在“多字节字符集 (MBCS)” 或 “ANSI” 项目下:
-
(也就是 没有定义
UNICODE宏) -
LPTSTR会被定义为LPSTR。 -
而
LPSTR本质上就是char*,即指向单字节字符(ANSI)字符串的指针。 -
你可以把它当作普通的C语言字符串来理解和使用。
-
-
在 “Unicode” 项目下:
-
(也就是 定义了
UNICODE宏) -
LPTSTR会被定义为LPWSTR。 -
而
LPWSTR本质上就是wchar_t*,即指向宽字节字符(Unicode)字符串的指针。
-
这个机制意味着,你在代码中统一使用 LPTSTR,然后通过修改项目设置中的一个开关,就能让整个程序在ANSI和Unicode字符集之间切换,这在当时是非常实用的设计。
2. 名称的含义
这个名字的每一个部分都有它的历史含义:
-
LP:Long Pointer(长指针)。这是从16位Windows系统时代遗留下来的术语,在32位和64位系统中,它就是一个普通的指针,没有实际意义了。
-
T:代表
TCHAR类型。表明这个指针指向的是TCHAR类型的数据,而TCHAR正是那个会根据UNICODE宏在char和wchar_t之间切换的“万能”字符类型。 -
STR:String(字符串)。表明这是一个指向字符串的指针。
3. 如何在VC++ 6.0中使用它
在 VC++ 6.0 环境中,你通常会看到它与 TCHAR 系列函数和宏一起使用。
-
定义变量:
c++
LPTSTR lpszMyString; // 声明一个指向字符串的指针 TCHAR szBuffer[128]; // 声明一个字符数组
-
使用字符串常量:
为了配合LPTSTR的自动适应,在定义字符串常量时,最好使用_T()或TEXT()宏。c++
// 如果项目是ANSI,_T("你好") 会被解释为 "你好" // 如果项目是Unicode,_T("你好") 会被解释为 L"你好" LPTSTR lpszString = _T("这是一段测试文字"); -
常用的相关类型:
你还会经常见到它的“亲戚”们:-
LPCTSTR:增加了一个C(const),表示这是一个 指向常量字符串的指针。它相当于const TCHAR*,用于只读字符串,防止被意外修改。 -
LPSTR:不带T,就是固定的char*(ANSI字符串)。 -
LPWSTR:带W(Wide),就是固定的wchar_t*(Unicode字符串)。
-
| 类型 | 含义 (ANSI/非Unicode环境) | 含义 (Unicode环境) |
|---|---|---|
| LPTSTR | char* (指向ANSI字符串) | wchar_t* (指向Unicode字符串) |
| LPCTSTR | const char* (指向常量ANSI字符串) | const wchar_t* (指向常量Unicode字符串) |
| TCHAR | char | wchar_t |
总结
对于正在使用 VC++ 6.0 的你来说,可以把 LPTSTR 理解为一个“智能”的字符串指针。如果你的项目是普通的控制台程序或MBCS程序,它就是一个 char*;如果你的项目是为了处理中文、日文等需要广泛字符集而设置了Unicode支持,它就自动变成了 wchar_t*。
为了方便和可移植性,在VC++ 6.0中处理字符串时,推荐使用 TCHAR、LPTSTR 和 _T() 宏这套组合。
PSTR LPSTR CHAR CHAR* LPTSTR
在VC++ 6.0中,这些类型都是用来表示字符串的,但它们之间有一些细微的区别。我来帮你理清它们的关系:
1. 基础类型关系图
text
CHAR* = char* (最基础的C语言字符串)
│
└── LPSTR = CHAR* = char* (Windows定义的ANSI字符串)
│
└── PSTR = LPSTR (完全等同,只是名字不同)
text
TCHAR* (根据宏定义变化)
│
├── 如果定义了 _UNICODE → wchar_t*
│
└── 如果没有定义 _UNICODE → char* = LPSTR
│
└── LPTSTR = TCHAR* (可变字符串指针)
2. 详细解释每个类型
CHAR
c
// WinDef.h 中的定义 typedef char CHAR;
-
就是C语言的
char类型 -
一个字节,用于存储ASCII字符
CHAR* 或 char*
-
指向CHAR的指针
-
C语言最原始的字符串表示方法
LPSTR
c
// WinDef.h 中的定义 typedef CHAR *LPSTR;
-
Long Pointer to STRing
-
指向ANSI字符串的长指针(32位指针)
-
等价于
char* -
多用于Windows API中处理ANSI字符串
PSTR
c
// WinDef.h 中的定义 typedef CHAR *PSTR;
-
Pointer to STRing
-
完全等同于
LPSTR -
只是名字不同,历史遗留原因
-
在VC++ 6.0中两者可以互换使用
LPTSTR
c
// WinNT.h 中的定义
#ifdef _UNICODE
typedef WCHAR *LPTSTR; // WCHAR = wchar_t
#else
typedef CHAR *LPTSTR; // CHAR = char
#endif
-
Long Pointer to TCHAR STRing
-
根据是否定义
_UNICODE宏自动适应 -
可移植性字符串类型
-
在VC++ 6.0默认设置下(ANSI),等同于
LPSTR
3. 实际使用示例
c
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
int main()
{
// 1. CHAR* / char* 的使用
char* p1 = "Hello ANSI"; // 标准C字符串
CHAR* p2 = "Hello CHAR*"; // 和上面完全一样
// 2. LPSTR 的使用
LPSTR p3 = "Hello LPSTR"; // 等同于 char*
LPSTR p4 = p2; // 可以和CHAR*互换
// 3. PSTR 的使用
PSTR p5 = "Hello PSTR"; // 完全等同于LPSTR
PSTR p6 = p3; // LPSTR和PSTR可以互换
// 4. LPTSTR 的使用(VC6默认是ANSI模式)
LPTSTR p7 = _T("Hello LPTSTR"); // _T宏适应字符集
// 5. 显示结果
printf("CHAR*: %s\n", p2);
printf("LPSTR: %s\n", p3);
printf("PSTR: %s\n", p5);
printf("LPTSTR: %s\n", p7);
return 0;
}
4. 常见Windows API调用示例
c
#include <windows.h>
int main()
{
// 情况1:用LPSTR调用API
LPSTR lpStr = "C:\\test.txt";
HANDLE hFile1 = CreateFileA(lpStr, GENERIC_READ, 0, NULL,
OPEN_EXISTING, 0, NULL);
// 情况2:用LPTSTR调用API(VC6默认ANSI)
LPTSTR lpStr2 = _T("C:\\test.txt");
HANDLE hFile2 = CreateFile(lpStr2, GENERIC_READ, 0, NULL,
OPEN_EXISTING, 0, NULL);
// 情况3:直接用char*
char* pFile = "C:\\test.txt";
HANDLE hFile3 = CreateFileA(pFile, GENERIC_READ, 0, NULL,
OPEN_EXISTING, 0, NULL);
return 0;
}
5. 总结对比表
| 类型 | 本质 | 是否可变 | 字符集 | 典型用途 |
|---|---|---|---|---|
| CHAR | char | 否(是字符) | ANSI | 单个字符 |
| CHAR* | char* | 是 | ANSI | C风格字符串 |
| LPSTR | char* | 是 | ANSI | Windows ANSI API |
| PSTR | char* | 是 | ANSI | 与LPSTR完全等同 |
| LPTSTR | TCHAR* | 是 | 自适应 | 可移植代码 |
6. 给VC++ 6.0用户的建议
-
新手入门:直接用
char*最简单,不容易出错 -
Windows编程:用
LPSTR更规范,符合API习惯 -
想写可移植代码:用
LPTSTR+_T()宏 -
注意:在VC6默认设置下,
LPTSTR=LPSTR=char*
一句话总结:在VC++ 6.0的默认配置下,CHAR*、LPSTR、PSTR、LPTSTR 其实都是 char*,可以互换使用。它们只是Windows为了代码清晰和可移植性而定义的不同名字。
把上面的整理成md我要做到CSDN的文章上面
markdown
# VC++ 6.0 中字符串类型详解:CHAR、LPSTR、PSTR、LPTSTR 在 Windows 编程,特别是 VC++ 6.0 环境中,字符串类型繁多,容易混淆。本文将详细解析 CHAR、LPSTR、PSTR、LPTSTR 这些类型的本质区别与联系。 ## 1. 类型关系总览
CHAR* = char* (最基础的C语言字符串)
│
└── LPSTR = CHAR* = char* (Windows定义的ANSI字符串)
│
└── PSTR = LPSTR (完全等同,只是名字不同)
text
TCHAR* (根据宏定义变化)
│
├── 如果定义了 _UNICODE → wchar_t*
│
└── 如果没有定义 _UNICODE → char* = LPSTR
│
└── LPTSTR = TCHAR* (可变字符串指针)
text
## 2. 各类型详细解析 ### CHAR ```c // WinDef.h 中的定义 typedef char CHAR;
-
本质:就是C语言的
char类型 -
大小:1个字节
-
用途:存储单个ASCII字符
-
特点:最基础的字符类型
CHAR* (char*)
-
本质:指向CHAR的指针
-
用途:C语言最原始的字符串表示方法
-
特点:标准C风格字符串
LPSTR
c
// WinDef.h 中的定义 typedef CHAR *LPSTR;
-
全称:Long Pointer to STRing
-
本质:指向ANSI字符串的长指针(32位指针)
-
等价于:
char* -
用途:Windows API中处理ANSI字符串
-
特点:Windows编程中最常见的ANSI字符串类型
PSTR
c
// WinDef.h 中的定义 typedef CHAR *PSTR;
-
全称:Pointer to STRing
-
本质:完全等同于
LPSTR -
特点:历史遗留原因造成的命名差异,两者可互换使用
LPTSTR
c
// WinNT.h 中的定义
#ifdef _UNICODE
typedef WCHAR *LPTSTR; // WCHAR = wchar_t
#else
typedef CHAR *LPTSTR; // CHAR = char
#endif
-
全称:Long Pointer to TCHAR STRing
-
本质:根据
_UNICODE宏自动适应的字符串类型 -
特点:
-
可移植性字符串类型
-
在VC++ 6.0默认设置(ANSI)下,等同于
LPSTR -
常与
_T()宏配合使用
-
3. 实际代码示例
3.1 基本使用示例
c
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
int main()
{
// 1. CHAR* / char* 的使用
char* p1 = "Hello ANSI"; // 标准C字符串
CHAR* p2 = "Hello CHAR*"; // 和上面完全一样
// 2. LPSTR 的使用
LPSTR p3 = "Hello LPSTR"; // 等同于 char*
LPSTR p4 = p2; // 可以和CHAR*互换
// 3. PSTR 的使用
PSTR p5 = "Hello PSTR"; // 完全等同于LPSTR
PSTR p6 = p3; // LPSTR和PSTR可以互换
// 4. LPTSTR 的使用(VC6默认是ANSI模式)
LPTSTR p7 = _T("Hello LPTSTR"); // _T宏适应字符集
// 5. 显示结果
printf("CHAR*: %s\n", p2);
printf("LPSTR: %s\n", p3);
printf("PSTR: %s\n", p5);
printf("LPTSTR: %s\n", p7);
return 0;
}
3.2 Windows API 调用示例
c
#include <windows.h>
int main()
{
// 情况1:用LPSTR调用API
LPSTR lpStr = "C:\\test.txt";
HANDLE hFile1 = CreateFileA(lpStr, GENERIC_READ, 0, NULL,
OPEN_EXISTING, 0, NULL);
// 情况2:用LPTSTR调用API(VC6默认ANSI)
LPTSTR lpStr2 = _T("C:\\test.txt");
HANDLE hFile2 = CreateFile(lpStr2, GENERIC_READ, 0, NULL,
OPEN_EXISTING, 0, NULL);
// 情况3:直接用char*
char* pFile = "C:\\test.txt";
HANDLE hFile3 = CreateFileA(pFile, GENERIC_READ, 0, NULL,
OPEN_EXISTING, 0, NULL);
return 0;
}
4. 类型对比表
| 类型 | 本质 | 是否指针 | 字符集 | 可变性 | 典型用途 |
|---|---|---|---|---|---|
| CHAR | char | 否 | ANSI | 不可变(字符) | 单个字符 |
| CHAR* | char* | 是 | ANSI | 可变 | C风格字符串 |
| LPSTR | char* | 是 | ANSI | 可变 | Windows ANSI API |
| PSTR | char* | 是 | ANSI | 可变 | 与LPSTR完全等同 |
| LPTSTR | TCHAR* | 是 | 自适应 | 可变 | 可移植代码 |
5. 相关辅助宏
_T() 或 TEXT() 宏
c
// 根据是否定义_UNICODE自动添加或省略L前缀
LPTSTR str = _T("This is a test");
// ANSI模式:等价于 "This is a test"
// Unicode模式:等价于 L"This is a test"
常用相关类型
| 类型 | 说明 | 等价于 |
|---|---|---|
| LPCTSTR | const LPTSTR | const TCHAR* |
| LPCSTR | const LPSTR | const char* |
| LPCWSTR | const LPWSTR | const wchar_t* |
6. VC++ 6.0 中的实际应用建议
6.1 不同场景的选择建议
| 使用场景 | 推荐类型 | 原因 |
|---|---|---|
| 新手学习 | char* | 简单直观,不易出错 |
| Windows API编程 | LPSTR | 符合API习惯,规范 |
| 可移植代码 | LPTSTR + _T() | 支持ANSI/Unicode切换 |
| 常量字符串 | LPCTSTR | 防止意外修改 |
| MFC编程 | CString | MFC封装好的字符串类 |
6.2 注意事项
-
VC++ 6.0 默认设置:在默认安装的VC++ 6.0中,项目默认不使用Unicode,因此:
-
LPTSTR=LPSTR=char* -
TCHAR=char -
_T("")=""
-
-
内存管理:这些类型都是指针,使用动态内存时需要自行分配和释放:
c
// 动态分配 LPTSTR pBuf = (LPTSTR)malloc(100 * sizeof(TCHAR)); // 使用... free(pBuf);
-
API函数对应:
c
// ANSI版本(A结尾) MessageBoxA(hWnd, lpStr, lpTitle, MB_OK); // Unicode版本(W结尾) MessageBoxW(hWnd, lpWStr, lpWTitle, MB_OK); // 通用版本(根据宏定义自动选择) MessageBox(hWnd, lpStr, lpTitle, MB_OK);
7. 常见问题解答
Q1: LPSTR 和 PSTR 到底有什么区别?
A: 没有本质区别!它们是同一个类型的两个不同名字,完全等价,可以互换使用。这只是Windows发展过程中的历史遗留问题。
Q2: VC++ 6.0 中 LPTSTR 到底是什么?
A: 在VC++ 6.0的默认设置下(未定义_UNICODE),LPTSTR 就是 LPSTR,也就是 char。只有当你手动在项目设置中启用Unicode支持后,它才会变成 wchar_t。
Q3: 我应该用哪种类型?
A:
-
如果你刚学C/C++:用
char*最直接 -
如果你在写Windows程序:用
LPSTR更规范 -
如果你想代码能在ANSI/Unicode间切换:用
LPTSTR+_T()宏 -
如果你用MFC:直接用
CString最方便
Q4: 为什么Windows要定义这么多字符串类型?
A: 主要是为了:
-
代码可读性:LPSTR明确表示这是一个"指向字符串的长指针"
-
可移植性:LPTSTR可以在ANSI和Unicode间切换
-
历史兼容:PSTR是更早的定义,LPSTR是为了强调"长指针"(16位时代)
8. 总结
在VC++ 6.0的默认配置下,CHAR*、LPSTR、PSTR、LPTSTR 本质上都是 char*,可以互换使用。它们只是Windows为了代码清晰、规范化和可移植性而定义的不同名字:
-
CHAR*:C语言原始风格
-
LPSTR:Windows ANSI编程标准
-
PSTR:LPSTR的别名
-
LPTSTR:可移植版本(默认=LPSTR)
理解这些类型的关系,对于阅读和编写Windows程序代码会很有帮助。
text
CHAR*:C语言原始风格 LPSTR:Windows ANSI编程标准 PSTR:LPSTR的别名 LPTSTR:可移植版本(默认=LPSTR)在VC6.0中都一样
你说得完全正确!在VC++ 6.0的默认配置下(未定义 _UNICODE 宏),这几者确实完全一样,都是 char*。
以下是精简版的总结,适合放在CSDN文章中作为结论部分:
一句话总结(VC++ 6.0 默认配置)
| 类型 | 本质 | 说明 |
|---|---|---|
| CHAR* | char* | C语言原始风格 |
| LPSTR | char* | Windows ANSI编程标准 |
| PSTR | char* | LPSTR的别名 |
| LPTSTR | char* | 可移植版本(默认=LPSTR) |
在VC++ 6.0默认设置下,这四种类型完全等价,都是 char*,可以互换使用。
验证代码
c
#include <windows.h>
#include <stdio.h>
#include <typeinfo.h>
int main()
{
CHAR* p1 = NULL;
LPSTR p2 = NULL;
PSTR p3 = NULL;
LPTSTR p4 = NULL;
printf("CHAR*: %s\n", typeid(p1).name());
printf("LPSTR: %s\n", typeid(p2).name());
printf("PSTR: %s\n", typeid(p3).name());
printf("LPTSTR: %s\n", typeid(p4).name());
return 0;
}
在VC6默认配置下,输出都是:
text
CHAR*: char * LPSTR: char * PSTR: char * LPTSTR: char *
注意事项
只有在项目设置中定义了 _UNICODE 宏时,LPTSTR 才会变成 wchar_t*,其他三个仍然保持 char*。
c
// 只有定义了 _UNICODE 时 // LPTSTR = wchar_t* // 其他三个仍然是 char*
这个区别在你做CSDN文章时可以作为一个进阶知识点提及。
450

被折叠的 条评论
为什么被折叠?



