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.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;
}

 

 

LPSTRLPCSTRLPTSTR 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());

 

 

字符串 的 ASCII UNICODE 之间的转换

 

 

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

 

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 的封装。

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/495697.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ofd电子文档内容分析工具(分析文档、签章和证书)

前言 ofd是国家文档标准&#xff0c;其对标的文档格式是pdf。ofd文档是容器格式文件&#xff0c;ofd其实就是压缩包。将ofd文件后缀改为.zip&#xff0c;解压后可看到文件包含的内容。 加入QQ交流群&#xff1a;618168615。获取下载程序。 ofd文件解压后&#xff0c;可以看到…

关于信任

[caption id"attachment_349" align"alignnone" width"374" caption"Trust is the most important thing to the team!"][/caption] 偶然间看到一张截图&#xff0c;是杭州小马哥不知何年何月何地做的show&#xff0c;这句话从他嘴里讲…

ES的安装和RestClient的操作

目录 初识elasticsearch 什么是elasticsearch elasticsearch的发展 Lucene的优缺点 elasticsearch的优势 倒排索引 es与mysql的概念对比 文档 索引 概念对比 架构 安装es 安装kibana 安装ik分词器 分词器 安装ik分词器 ik分词器的拓展和停用词典 操作索引库…

深度 | 智慧•城市,基于国际视野下的思考

来源&#xff1a;智慧城市决策参考智慧城市的兴起&#xff0c;得益于ICT技术的迅猛发展。经过这些年国内外诸多城市的探索和实践&#xff0c;智慧城市已经从最初的营销概念&#xff0c;逐渐发展成为一种支持城市发展的新理念。然而在实际应用中&#xff0c;智慧城市的内涵仍然是…

__cdecl、__stdcall、__fastcall 与 __pascal 浅析

X86调用约定 calling convention&#xff1a;https://www.cnblogs.com/shangdawei/p/3323252.html__cdecl、__stdcall、__fastcall 与 __pascal 浅析&#xff1a;https://www.cnblogs.com/yenyuloong/p/9626658.html王爽 汇编语言第三版 第9章 转移指令的原理&#xff1a;https…

全文详解:「深度学习」如何协助处理医疗中的「数据难题」

原文来源&#xff1a;WordPress作者&#xff1a;Luke Oakden-Rayner「雷克世界」编译&#xff1a;嗯~是阿童木呀、KABUDA、EVA医疗数据很难处理。在医学成像中&#xff0c;数据存储&#xff08;档案&#xff09;是基于临床假设进行操作的。不幸的是&#xff0c;这意味着当你想提…

Android应用程序变量

Android应用程序开发中&#xff0c;有的时候我们在应用程序的任何一个地方都需要访问一个全局变量&#xff0c;也就是在任何一个Activity中都可以访问的变量。它不会因为Activity的生命周期结束而消失。要实现应用程序级的变量&#xff0c;我们可以通过Application这个类来实现…

百度谷歌等联合推出机器学习基准 加速AI软硬件发展

来源&#xff1a;中国新闻网5月2日&#xff0c;由包括百度、谷歌、斯坦福大学、哈佛大学在内的多家企业和高校联合发布了一套用于测量和提高机器学习软硬件性能的国际基准MLPerf。其巨大的学术和产业价值获业界肯定&#xff0c;被认为不仅将加速推进机器学习硬件软件相关技术创…

王爽 汇编语言第三版 第10章 call 和 ret 指令 以及 子程序设计

第10章 call 和 ret 指令 10.1 ret 和 reft 指令 call 和 ret 指令都是转移指令&#xff0c;他们都修改 IP&#xff0c;或同事修改 CS 和 IP 。他们经常被共同来实现子程序的设计。 10.2 call 指令 和 根据位移 转移的call指令 段间转移 的 call 指令 转移地址 在 寄存器 中 的…

org/apache/maven/cli/MavenCli : Unsupported major.minor version 51.0

一、错误现象&#xff1a; 当改变了jdk版本时&#xff0c;在编译java时&#xff0c;会遇到Unsupported major.minor version错误。 jdk版本和stanford parser对应关系 JDK版本和Java编译器内部的版本号 J2SE 8 52, J2SE 7 51, J2SE 6.0 50, J2SE 5.0 49, JDK 1.4 48, J…

ip, tcp, udp, icmp header

Figure 1. IPv4 header Figure 2. TCP header Figure 3. UDP header Figure 4. ICMP header reference:TCP/IP Reference转载于:https://www.cnblogs.com/lbsx/archive/2010/11/30/1891814.html

人民日报三问人工智能,给法律制度带来哪些挑战?

来源&#xff1a;亿欧网 作者&#xff1a;倪弋摘要&#xff1a;人工智能生成物是否具有知识产权&#xff1f;人工智能可以替代司法者吗&#xff1f;人工智能侵权责任如何认定&#xff1f;人工智能的出现会给现行的法律制度带来了不少挑战&#xff0c;只有在法律研究上未雨绸缪…

测试用例设计--判定表

一. 判定表 定义判定表通常由四部分组成&#xff0c;如上图&#xff1a; 条件桩 : 它列出决定一组条件的对象&#xff1b; 条件项: 它列出各种可能的条件组合&#xff1b; 动作桩: 它列出所有的操作; 动作项: 它列出在对应的条件组合下的动作. 应用的范围在多个条件决定多个动…

王爽 汇编语言第三版 第11章 标志寄存器

条件码&#xff1a; ① OF(Overflow Flag)溢出标志&#xff0c;溢出时为1&#xff0c;否则置0.标明一个溢出了的计算&#xff0c;如:结构和目标不匹配.② SF(Sign Flag)符号标志&#xff0c;结果为负时置1&#xff0c;否则置0.③ ZF(Zero Flag)零标志&#xff0c;运算结果为0时…

Gartner:预计2018年人工智能行业总价值达1.2万亿美元

来源&#xff1a;网络大数据市场研究公司Gartner周三发布最新研究报告称&#xff0c;人工智能行业的总价值将在2018年达到1.2万亿美元&#xff0c;比2017年增长70%。其中&#xff0c;创造商业价值最大的领域是客户体验解决方案。该公司还预计&#xff0c;到2022年的时候&#x…

JAVA将html[动态]页面转成图片

近日项目上接到一个任务&#xff0c;设计并编写住院病案首页页面&#xff0c;然后将其转换成图片显示给医生查看。 天哪&#xff0c;住院病案内容那么多&#xff0c;光编写这个页面就已经够呛了&#xff0c;转图片我也没弄过&#xff0c;于是百度了一下&#xff0c;花了两天时间…

王爽 汇编语言第三版 课程设计 1

From&#xff1a;https://www.cnblogs.com/Since-natural-ran/p/6938133.html 汇编语言-课程设计1: https://www.cnblogs.com/tsembrace/p/3267158.html 王爽课程设计1(汇编语言编写): https://www.imooc.com/article/18785 王爽《汇编语言》课程设计1: https://blog.csdn.net/…

挑战权威还是偏离主流?颠覆性研究或将证明神经信号是机械波

来源&#xff1a;科研圈 翻译 马骁骁 编辑 魏潇 廖红艳就职于哥本哈根尼尔斯玻尔研究所&#xff08;Niels Bohr Institute&#xff09;的托马斯亨伯格&#xff08;Thomas Heimburg&#xff09;&#xff0c;是一位研究量子力学和生物物理的物理学家。然而&#xff0c;他却希…

史上最全的女人坐月子注意事項

希望男人们要精心照顾好妻子&#xff0c;让妻子平安度过这一时期&#xff0c;为了宝宝&#xff0c;为了你们的幸福&#xff0c;因为你爱她就要呵护她&#xff0c;她好你也好&#xff0c;她平安就是你们全家的幸福&#xff0c;精致女人把祝福送给你们&#xff01; 传统上人们将产…

斯坦福大学、DARPA与硅谷公司共同分析前沿科技发展趋势

来源&#xff1a;科技日报 作者&#xff1a;张梦然日前&#xff0c;斯坦福大学研究团队、美国国防部高级研究计划局&#xff08;DARPA&#xff09;以及硅谷创投公司和米资本的专家们&#xff0c;共同研讨了技术将如何重塑行业和社会等问题。他们分析了现今全球前沿科技的未来…