std::字符串到LPCTSTR
std::string to LPCTSTR
如何从std::string
转换为LPCTSTR
的典型问题的新版本。
从不同的SO帖子中,我了解到我应该这样做:
CreateDirectory(path.c_str(),NULL);
但由于cannot convert from const char * to LPCTSTR
。
我试过了:
CreateDirectory((LPCTSTR)path.c_str(),NULL);
没有错误!
仍然创建的目录(在正确的位置(被称为:
D:\something\㩄ぜ弲久䅓余屓䱆彄湡敤屲䵉ⴱ㠶ⴰⵃㅇ㉜洰就䥄牃獥汵獴촀췍췍췍췍췍췍췍﷽ꮫꮫꮫﺫﻮﻮ
正如你所猜测的,这并不是我想要的。。。
那么我错过了什么?它与UNICODE/ANSI有关吗?我该如何解决此问题?
试着看看这个页面:What-are-TCHAR-WCHAR-LPSTR-LPWSTR-LPCTSTR-etc。如果您使用的是MSVC,那么您可能已经为项目设置了Unicode,并且LPCSTR
被"翻译"为const wchar_t *
,这与const char *
不兼容
通过这样做:(LPCTSTR)path.c_str()
,您将从原始字符串中提取两个字符,并从中创建一个unicode wchar_t字母。这就是你获得"中文"字符的方式。
您的问题是,根据您的构建是否支持unicode(unicode标志集(,LPCTSTR
被解析为wchar_t*
或char*
。
要显式调用char*
版本,请调用CreateDirectoryA()
。
当您试图找到"(std::(string to LPCTSTR"时,会弹出此问题
以下是如何转换&使用wstring
将std::string
作为LPCTSTR
传递
string path_str = "Yay!"; //your string containing path
wstring path_wstr( path_str.begin(), path_str.end() );
//then this should work:
CreateDirectory(path_wstr.c_str(),NULL);
重要提示作者:Adrian McCarthy:
如果源字符串是ASCII或者是ANSI并且当前的代码页是Windows-1252(和Latin-1非常相似(。如果源代码是UTF-8或其他代码页,那么这只会隐藏问题
您正在为Unicode进行编译,这意味着CreateDirectory
是宽字符版本CreateDirectoryW
的别名。但是,程序中的文本是使用ANSI编码的。这意味着您的程序无法正确处理国际化。
编译器告诉您,CreateDirectoryW
期望的文本编码与您提供的文本编码不匹配。的确,您可以调用CreateDirectoryA
来解决错误匹配,但这只会使根本问题永久化,即您在程序中使用ANSI文本。
因此,最好的解决方案是开始将所有文本编码为Unicode。停止使用string
,开始使用wstring
。一旦您将path
更改为wstring
,则
CreateDirectory(path.c_str(),NULL);
是正确的。
请改用CreateDirectoryA
。CCD_ 25是根据构建配置扩展到CCD_ 26或CCD_ 27的宏;分别取CCD_ 28和CCD_。如果你知道你有一个LPCSTR
(这就是c_str()
给你的(,那就用第一个。
其他解释是正确的:
与许多Window API一样,CreateDirectory实际上是一个扩展到"ANSI"或"Wide"版本的宏,具体取决于是否定义了UNICODE
。ANSI版本有效地将单字节字符串转换为宽字符串,然后委托给宽字符串版本。
然而,直接调用CreateDirectoryA的建议也有一些缺点:
"ANSI"API进行的转换假定源字符串编码在用户的当前代码页中。在简单的情况下,这很可能是真的。但在许多现实生活中的代码中,情况并非如此。因此,你可能会得到错误类型的转换,这会导致你稍后会发现的错误。至少糟糕的类型转换会导致你立即发现错误。
更好的解决方案是在整个过程中使用宽字符串(std::wstring(,并调用CreateDirectoryW。没有转换出错。不需要类型转换。
对于许多代码库来说,重写所有内容以使用宽字符串是不现实的。事实证明,有充分的理由采取相反的做法,继续使用std::字符串,但要标准化,使其包含UTF-8文本。然后,当您必须调用Windows API时,您将转换(而不是类型转换(为UTF-16,并直接调用API的宽版本。这会以进行一些转换和一些临时缓冲为代价,为您提供完全的保真度。由于这些类型的电话很少出现在热点地区,因此费用通常不会太大。
在Windows上,要在UTF-8和UTF-16之间转换,可以调用MultiByteToWideChar/WideCharToMultiByte,代码页设置为CP_UTF8。
我已经为此奋斗了很长一段时间。经过一番挖掘,我发现这是最好的作品;你可以尝试以下方法:
std::string t = "xyz";
CA2T wt (t.c_str());