std::字符串到LPCTSTR

std::string to LPCTSTR

本文关键字:LPCTSTR 字符串 std      更新时间:2023-10-16

如何从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"时,会弹出此问题

以下是如何转换&使用wstringstd::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());