From:https://www.cnblogs.com/leanee/articles/2940088.html

char [] 到 LPWSTR转换的一个具体应用:http://www.cppblog.com/lateCpp/articles/153358.html

CString详细讲解:https://blog.csdn.net/qq_41786318/article/details/81989217

CString 应用操作指南【转】:https://blog.csdn.net/iteye_13411/article/details/82092838

VS2010/MFC编程入门之四十二(MFC常用类:CString类)
http://www.jizhuomi.com/software/228.html

因为 C++ 支持两种字符串 :

  • 1. 常规的 ANSI 编码(使用 "" 包裹)
  • 2. Unicode 编码(使用 L"" 包裹)

UNICODE 宏 和 _UNICODE 宏 (Windows 核心编程 第五版 2.4 节

这样对应的就有了两套字符串字符串处理函数,比如:strlen 和 wcslen,分别用于处理两种字符串。微软将这两套字符集及其操作进行了统一,通过条件编译(通过 _UNICODE 和 UNICODE 宏)控制实际使用的字符集,这样就有了 _T("") 这样的字符串,对应的就有了_tcslen 这样的函数。为了存储这样的通用字符,就有了TCHAR:

  • 当 没有定义  _UNICODE宏 时,TCHAR = char,_tcslen = strlen
  • 当 定义 _UNICODE宏 时,TCHAR = wchar_t , _tcslen = wcslen[1]

当我们定义了 UNICODE宏,就相当于告诉了编译器:我准备采用 UNICODE 版本。这个时候,TCHAR 就会摇身一变,变成了wchar_t 。而未定义 UNICODE宏 时,TCHAR 摇身一变,变成了unsigned char。这样就可以很好的切换宽窄字符集。
tchar 可用于双字节字符串,使程序可以用于中日韩等国 语言文字处理、显示。使编程方法简化。

C++ 中的 wchar_t 数据类型

标准里面是这样解释的:Wide character ( 宽字节字符 )
Type whose range of values can represent distinct codes for all members of the largest extended character set specified among the supported locales.
In C++, wchar_t is a distinct fundamental type (and thus it is not defined in <cwchar> nor any other header).
在 C++ 中,wchar_t 是一个特有的基本类型( 因此它并没有在 <cwchar> 或其他 header 中被定义)
In C, this is a typedef of an integral type.( 在 C 中,wchar_t 是一个整数类型的 typedef )

wchar_t  是 C/C++ 的字符类型,一种扩展的存储方式,主要用在国际化程序的实现中。
char 是8位字符类型,最多能包含256种字符,许多的外文字符集所包含的字符数目超过256个,char 型不能表示。比如对于汉字,韩文以及日文这样的字符,它们的每一个文字都占据两个字节,所以 C++ 提出了 wchar_t 类型,也称为双字节类型,或宽字符类型。

截图来自:windows 核心编程 第五版 第二章 2.2 ANSI字符和Unicode字符与字符串数据类型

示例代码:

#include <iostream>
#include <locale>           //setlocale函数在locale头文件中定义
using namespace std;
int main()
{//使用setlocale函数将本机的语言设置为中文简体//LC_ALL表示设置所有的选项(包括金融货币、小数点,时间日期格式、语言字符串的使用习惯等),chs表示中文简体setlocale(LC_ALL, "chs");wchar_t wt[] = L"中国伟大复兴梦";   //大写字母L告诉编译器为"中"字分配两个字节的空间wcout << wt << endl;               //使用wcout来代替cout输出宽字符return 0;
}

LPSTR、LPCSTR、LPTSTR 和 LPCTSTR 的意义及区别

  • 1、ANSI( 即 MBCS ):为 多字节字符集它是不定长表示世界文字的编码方式。ANSI 表示英文字母时就和 ASCII 一样,但表示其他文字时就需要用多字节。
  • 2、Unicode:用两个字节表示一个字符的编码方式。比如 字符  'A'  在 ASCII 下面用一个字节表示,而在 Unicode 下面用两个字节表示,其中高字节用 “0” 填充;中文字符  '程' 在 ASCII 下面用两个字节表示,而在 Unicode下面也是用两个字节表示。Unicode 的用处就是定长表示世界文字,据统计,用两个字节可以编码现存的所有文字而没有二义。
  • 3、Windows 下的程序设计可以支持 ANSI 和 Unicode 两种编码方法的字符串,具体使用哪种就要看定义了 MBCS宏 还是Unicode宏。MBCS宏 对应的字符串指针为 LPSTR( 即 char* ),Unicode 对应的指针为 LPWSTR( 即 unsigned char* )。为了写程序的方便,微软定义了类型 LPTSTR,在 MBCS 下它表示 char*,在 Unicode 下它表示 unsigned char*,这就可以重定义一个宏进行不同字符集的转换了。
  • 4、关系。
            LPSTR:   LPSTR = char*;  指向一个字符串的32位指针,每个字符占1个字节。
            LPCSTR: LPCSTR = const char*;指向一个常量字符串的32位指针,每个字符占1个字节。
            LPTSTR:指向一个字符串的32位指针,每个字符可能占1个字节或2个字节。
            LPCTSTR:指向一个常量字符串的32位指针,每个字符可能占1个字节或2个字节。        
                   LPWSTR = wchar_t*;L            PCWSTR = const wchar_t*;

    多字节 编码: char,string,CStringA。
    Unicode 编码:wchar_t,wstring,CStringW。
    注意:如果项目是 Unicode,那么 CString 就被定义为 CStringW,否则就是 CStringA。

    至于 LPCTSTR 也是根据项目字符集来定义为 LPCWSTR(Unicode)或 LPCSTR(多字节)。
    OK,上面的定义很明显了,注意用的时候别弄混了,最好的方式是使用 wchar_t 和 wstring( api大多使用 unicode,即使是多字节版本也是把多字节转成 unicode 再去调用 unicode 版 api )

  • 5、Windows 使用两种字符集 ANSI 和 Unicode,前者在处理英文字符时使用单字节方式,在处理中文字符时使用双字节方式。后者不管是英文字符还是中文字符都是采用双字节方式表示。Windows NT的所有与字符有关的函数都提供了两种方式的版本,而 Windows 9x 只支持 ANSI 方式。_T 一般同字符常量相关,如 _T("你好!"); 。如果编码方式为 ANSI,_T 不起任何作用;如果编码方式为 Unicode,编译器会把 "你好!" 以 Unicode 方式进行保存。 _T 和 _L 的区别在于,_L 不管你是以什么方式编译,一律以 Unicode 方法保存。
  • 6、L 表示 字符串 采用 Unicode 编码方式,
            示例如下:wchar_t Str[] = L"Hello World!";     // 每个字符都用2个字节来存储
  • 7、_T 是一个适配宏。当定义了 _UNICODE 时,_T 和 L 相同;否则,_T 的字符串采用 ANSI 编码方式。
        示例如下:
            LPTSTR lptStr = new TCHAR[32];
            TCHAR* szBuf = _T("Hello");
        以上两个语句,无论是在 ANSI 编码方式,还是在 Unicode 编码方式下都是正确的。
  • 8、微软推荐使用相匹配的字符串函数。例如,在处理 LPTSTR 或 LPCTSTR 的时候,应该使用 _tcslen 来替代 strlen 函数。否则,在 Unicode 编码方式下,strlen 不能处理 wchar_t* 的字符串。
  • 9、T 是一个非常重要的符号TCHAR、LPTSTR、LPCTSTR、_T() 和 _TEXT() 等 ),它表示使用一个中间类型,既不明确表示使用 MBCS,也不明确表示使用 Unicode。到底使用哪种字符集,在编译的时候才决定。
  • 10、注意 L 和 _T 的使用方法。
      LPTSTR,LPCTSTR,及 _T(常量字符串) 受 _T 影响。
      介绍字符串类型:char, wchar_t,TCHAR, CHAR, WCHAR。
      TCHAR 的定义:
      #ifdef UNICODE 
          typedef wchar_t TCHAR; 
      #else 
          typedef unsigned char TCHAR; 
      #endif 
      
      typedef unsigned char CHAR; 
      typedef unsigned wchar_t WCHAR; 
      
    由此可以看出,unsigned char 和 wchar_t 都是基本数据类型,CHAR 实施上就是 unsigned char, WCHAR 为 wchar_t ,而 TCHAR 根据是否支持 unicode 而不同。在程序中,可以用的名称有5种,unsigned char(CHAR),wchar_t(WCHAR),TCHAR,但为了扩展性和兼容性,推荐使用 TCHAR。
  • 11、CString 类型到 LPTSTR 类型的转换
            CString path1;
            LPTSTR path2 = path1.GetBuffer(path1.GetLenght());

字符串 的 ASCIIUNICODE 之间的转换

Win32 提供了 API 函数 MultiByteToWideCharWideCharToMultiByte 来提供这种功能

char* 转换成 LPCTSTR。代码如下:

int MultiByteToWideChar()函数。根据 MSDN 描述,这个方法:This function maps a character string to a wide-character (Unicode) string。

char text[20] = "hello world";
TCHAR buffer[50];
MultiByteToWideChar(0, 0, text, -1, buffer, 20);char ch[1024] = "hello world";
int num = MultiByteToWideChar(0,0,ch,-1,NULL,0);
wchar_t *wide = new wchar_t[num];
MultiByteToWideChar(0,0,ch,-1,wide,num);解析:
num 获得长字节所需的空间
MultiByteToWideChar() 表示将 ch 中的字符传递到 wide 指向的内存中。
-1 表示传输至ch中的'\0'处,
num 表示传递的字节个数。

总结:MultiByteToWideChar()函数,首先得用 TCHAR 来定义一个数组

另外:网上有另外推荐将项目的 unicode 环境关掉,就可避免这个问题。不推荐,这实际上是回避问题。现在已经是 Unicode 的应用已经越来越广,程序不支持 Unicode 环境,走的了一时,走不了一世。

LPCTSTR 转换成 char *

wchar_t widestr[1024] = L"hello world";
int num = WideCharToMultiByte(CP_OEMCP, NULL, widestr, -1, NULL, 0, NULL, FALSE);
char *pchar = new char[num];
WideCharToMultiByte (CP_OEMCP, NULL, widestr, -1, pchar, num, NULL, FALSE);

一. CString 与 LPCWSTR

两者的不同:LPCWSTR 是 Unicode 字符串指针,初始化时串有多大,申请空间就有多大,以后存贮若超过则出现无法预料的结果,这是它与 CString 的不同之处。而 CString 是一个 字符串类,内存空间类会自动管理。

CString 转换成 LPCWSTR

方法 1:

CString strFileName;
LPCWSTR lpcwStr = strFileName.AllocSysString();

方法 2:CString str=_T("TestStr");

CString str=_T("TestStr");
USES_CONVERSION;
LPCWSTR lpcwStr = A2CW((LPCSTR)str);

MFC 中 CString 和 LPSTR 是可以通用,其中 A2CW 表示 (LPCSTR)  -> (LPCWSTR),USER_CONVERSION 表示用来定义一些中间变量,在使用 ATL 的转换宏之前必须定义该语句。

LPCWSTR 转换成 CString

LPCWSTR lpcwStr = L"TestWStr";
CString str(lpcwStr);

二. CString 与 LPSTR 转换

CString 转换成 LPSTR

方法一:

CString strFileName;
LPSTR lpStr = strFileName.GetBuffer();
strFileName.ReleaseBuffer();

方法二:

CString strFileName;
LPSTR lpStr = (LPSTR)(LPCSTR)strFimeName;

LPSTR 转换成 CString

LPSTR lpStr = L"TestStr";
CString str(lpStr);

注意:CString 和 LPCSTR 可直接转换,如下:

CString str;
LPCSTR lpcStr = (LPCSTR)str;

三. CString 和 char* 转换

CString 转换成 char*

方法 1:

CString str;
char* p = str.GetBuffer();

方法 2:

CString str;
char* p = (LPSTR)(LPCSTR)str;

char* 转换成 CString

char* p = "test";
CString str = ("%s",p);

四. String 和 int、float 的转换

可以使用 atoi、atof、atol 等函数来完成。

五. LPSTR (char*) 和 LPWSTR 的转换

可以使用下面的ATL宏来进行,最好是将变量定义成 TCHAR、LPTSTR 等T类型,可以避免转换

ATL宏介绍:

A2BSTR   OLE2A             T2A            W2A 
     A2COLE   OLE2BSTR    T2BSTR    W2BSTR 
     A2CT         OLE2CA         T2CA          W2CA 
     A2CW        OLE2CT         T2COLE    W2COLE 
     A2OLE       OLE2CW       T2CW         W2CT 
     A2T            OLE2T            T2OLE        W2OLE 
     A2W           OLE2W          T2W             W2T

A :ANSI 字符串,也就是 MBCS。 
    W、OLE 宽字符串,也就是 UNICODE。 
    T 中间类型T。如果定义了 _UNICODE,则T表示W;如果定义了 _MBCS,则T表示A 
    C const 的缩写

利用这些宏,可以快速的进行各种字符间的转换。使用前必须包含头文件,并且申明USER_CONVERSION;使用 ATL 转换宏,由于不用释放临时空间,所以使用起来非常方便。但是考虑到栈空间的尺寸(VC 默认2M),使用时要注意几点:

1、只适合于进行短字符串的转换; 
    2、不要试图在一个次数比较多的循环体内进行转换; 
    3、不要试图对字符型文件内容进行转换,因为文件尺寸一般情况下是比较大的; 
    4、对情况 2 和 3,要使用 MultiByteToWideChar() 和 WideCharToMultiByte();

void Func1(LPSTR lpStr);

void Func2(LPWSTR lpwStr);

TCHAR   name[256];

TCHAR*   pName = new  TCHAR[256];

Func1(name); // Func1(pName);

Func2(name); // Func2(pName);

注意在VS2005中上面用红色标记的代码已经不成立。

VS2005中CString已经改为宽字符型,一些转换如下:

char name[10];
 TCHAR sex[5] ;
 char *p = name;
 TCHAR *pw = sex;

LPSTR lpstr = name;
 LPCSTR lpcstr = name;
 lpcstr = lpstr;
 
 lpstr = p;
 p = (char*)sex;
 pw = (WCHAR*)name;
 LPWSTR lpwstr = (LPWSTR)lpstr;
 lpwstr = (LPWSTR)lpcstr;
 LPCWSTR lpcwstr = (LPCWSTR)lpstr;
 lpcwstr = (LPCWSTR)name;

CString str(lpstr);
 CString str1(lpcstr);
 CString str2(lpwstr);
 CString str3(lpcwstr);
 CString str4(name);
 CString str5(sex);

lpwstr = (LPWSTR)(LPCWSTR)str;
 lpstr = (LPSTR)(LPCWSTR)str;
 lpcstr = (LPCSTR)(LPCWSTR)str;

p = (char*)str.GetBuffer();
 pw = str.GetBuffer();

可以看出转换更加简单了,基本上可以直接转换,A2W 等宏基本上不需要啦。

接下来就是转换:

// C++
char*  到 string:string str("char"); 或者 string str = "char";
string 到 char*: const char* ch = str.c_str();
wchar_t* 和 wstring 与上相同。

// MFC

char* 到 CStringA:CStringA str("char");
CStringA 到 char*:const char* ch = str.operator LPCSTR(); 
注意:反对使用 GetBuffer,因为使用这个,必须要 ReleaseBuffer,而且很多时候没必要去分配空间
wchar_t* 和 CStringW 与上相同。

// 字符集之间转换
char* 到 wchar_t*:CA2W a2w("char");  const wchar_t* wch = a2w.operator LPCWSTR();
wchar_t* 到 char*:CW2A w2a(L"wchar_t"); const char* ch = w2a.operator LPCSTR();  (注意:反对使用_T("chs")这种方式,程序字符集在一开始就该确定,而且最好选择Unicode)

关于 CA2W 和 CW2A 这两个类,可以在 atlconv.h 中找到源代码,其实就是对 WideCharToMultiByte 和 MultiByteToWideChar 的封装。

CString 与 LPCWSTR、LPSTR、char*、LPWSTR 等类型的转换相关推荐

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

    CString与LPCWSTR.LPSTR.char*.LPWSTR等类型的转换 VC++ 2010-09-25 21:23:12 阅读457 评论3   字号:大中小 订阅 一.CString与LP ...

  2. CString 和 LPCTSTR 之间的转换 及 LPSTR、LPWSTR、LPCSTR、LPCWSTR、LPTSTR、LPCTSTR的区分与转化

    欢迎大家有空可以看下我的http://ltdzhuwai.taobao.com 今天在写代码的时候碰到这样的问题,网上查了一下,做了以下整理: CString   和   LPCTSTR   可以说通 ...

  3. cstringw转lpctstr_CString 和 LPCTSTR 之间的转换 及 LPSTR、LPWSTR、LPCSTR、LPCWSTR、LPTSTR、LPCTSTR的区分与转化...

    CString 和 LPCTSTR 可以说通用. 原因在于CString定义的自动类型转换,没什么奇特的,最简单的C++操作符重载而已. 常量字符串ansi和unicode的区分是由宏_T来决定的.但 ...

  4. Cstring转LPWSTR/LPCWSTR..BSTR、LPSTR、LPWSTR、CString、VARIANT、COleVariant 、_variant_t、CComBSTR、_bstr_t .

    //方法一  CString str=_T("TestStr");  USES_CONVERSION;  LPWSTR pwStr=new wchar_t[str.GetLengt ...

  5. char 类型与lpcwstr_CString与LPCWSTR、LPWSTR等数据类型的转换 | 学步园

    CString与LPCWSTR.LPWSTR等数据类型的转化 之前我遇到过类似的问题,在以前两篇博文中也提到过类似编码问题: 1. CString与LPCWSTR的转换 LPCWSTR 是Unicod ...

  6. LPSTR、LPWSTR、LPCSTR、LPCWSTR、LPTSTR、LPCTSTR的区分与转化

    首先在编译程序时经常会遇到这种问题: 错误 1 error C2664: "CWnd::MessageBoxW": 不能将参数 1 从"const char [3]&qu ...

  7. 【整理】Dword、LPSTR、LPWSTR、LPCSTR、LPCWSTR、LPTSTR、LPCTSTR

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

  8. BSTR、LPSTR、LPWSTR、CString、VARIANT、COleVariant 、_variant_t、CComBSTR、_bstr_t

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! Visu ...

  9. LPSTR/LPCSTR/LPWSTR/LPCWSTR/LPTSTR/LPCTSTR字符串指针

    LPSTR = char* LPCSTR = const char*LPWSTR = wchar_t* LPCWSTR = const wchar_t*LPTSTR = char* or wchar_ ...

最新文章

  1. Swift 中使用Alamofire 免证书的设置
  2. 为什么我不在微信公众号上写文章
  3. Java如何比较两个字符串(对象)是否相等
  4. 高德纳咨询公司(Gartner)预测:2019年七大人工智能科技趋势
  5. SpringMVC中使用Interceptor拦截器
  6. 解决MSSQL MMC企业管理器打开报错问题
  7. c语言补全 subilme_Sublime Text3 C语言插件
  8. java泛型面试_Java泛型面试问题
  9. Utility.cpp的函数
  10. 内蒙古农大孙志宏教授证实超深度混合宏基因组测序能够对人类肠道微生物组中的低丰度物种进行基因组和功能表征...
  11. dojo.declare
  12. 微软公司2008新技术预览大会
  13. linux执行多个命令_您必须知道的前50多个Linux命令
  14. 让li不显示超出内容,显示... (编程方法和CSS方法)
  15. Atitit 深入理解软件的本质 attilax总结 软件三原则三次原则是DRY原则和YAGNI原则的折
  16. 深入解析WINDOWS操作系统
  17. ukey网络连接异常_Ukey的各种操作,你知道吗?
  18. 数字图像处理·SLIC超像素分割算法C++实现
  19. 创建express项目及npm start报错解决办法
  20. Java中notify和notifyAll的区别 - 何时以及如何使用

热门文章

  1. 计算机应用基础doc,统考计算机应用基础大全.doc
  2. ubuntu下opencv图像编程
  3. lvm android分区合并,Linux LVM 分区扩容与多磁盘分区合并处理
  4. 重启linux服务器
  5. 艾妮教务系统使用体验
  6. 致ITFriend用户
  7. [转bbs] 当一个男的真正爱你的时候
  8. URL中文传输乱码解决
  9. 深入了解ApusicAS服务器配置系列之——SSL配置
  10. 學説韓國話,較實用的 [精华] (转帖)