std :: string到LPCTSTR

时间:2013-05-23 10:09:02

标签: c++ windows string

如何从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有关吗?我该如何解决这个问题?

7 个答案:

答案 0 :(得分:6)

这里的问题是LPCTSTR根据您的构建是否支持unicode(unicode标志设置与否)而解析为wchar_t*char*

要明确调用char*版本,请致电CreateDirectoryA()

答案 1 :(得分:6)

当你试图找到"(std::)字符串到LPCTSTR"

时弹出这个问题

以下是如何使用std::string

LPCTSTR转换为wstring的方法
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或其他代码页,那么这只是隐藏了   问题

答案 2 :(得分:5)

尝试查看此页面:What-are-TCHAR-WCHAR-LPSTR-LPWSTR-LPCTSTR-etc。如果您使用的是MSVC,那么您可能已经为项目设置了Unicode,而LPCSTR是"翻译的"至const wchar_t *,与const char *

不兼容

通过执行此操作:(LPCTSTR)path.c_str()您从原始字符串中获取两个字符,并从中创建一个unicode wchar_t字母。多数民众赞成你得到的方式" chinese"字符。

答案 3 :(得分:5)

您正在编译Unicode,这意味着CreateDirectoryCreateDirectoryW的别名,宽字符版本。但是,程序中的文本使用ANSI进行编码。这意味着您的程序无法正确处理国际化。

编译器告诉您CreateDirectoryW期望的文本编码与您提供的文本编码之间存在不匹配。确实,您可以调用CreateDirectoryA来解决该不匹配问题,但这只会使根问题永久化,即您在程序中使用ANSI文本这一事实。

因此,最好的解决方案是将所有文本编码为Unicode。停止使用string并开始使用wstring。将path更改为wstring后再

CreateDirectory(path.c_str(),NULL);

是对的。

答案 4 :(得分:1)

请改用CreateDirectoryACreateDirectory是一个扩展为CreateDirectoryACreateDirectoryW的宏,具体取决于构建配置;他们分别采用LPCSTRLPCWSTR。如果您知道自己有LPCSTR(这是c_str()给您的),请使用第一个。

答案 5 :(得分:1)

其他解释是正确的:

与许多Window API一样,

CreateDirectory实际上是一个扩展为“ANSI”或“Wide”版本的宏,具体取决于是否定义了UNICODE。 ANSI版本有效地将单字节字符串转换为宽字符串,然后委托给宽字符串版本。

但是,直接调用CreateDirectoryA的建议有一些缺点:

“ANSI”API完成的转换假定源字符串在用户的当前代码页中进行编码。在简单的情况下,这可能是真的。但在许多现实代码中,它并非如此。因此,您最终可能会遇到错误的转换类型,从而导致您稍后会发现错误。至少坏的类型转换会导致你立即发现的错误。

更好的解决方案是在整个过程中使用宽字符串(std :: wstring),并调用CreateDirectoryW。没有转换出错。不需要类型转换。

对于许多代码库,重写所有内容以使用宽字符串是不实际的。事实证明,有充分的理由完全相反并继续使用std :: strings,但要标准化它们hold UTF-8 text。然后,当您必须调用Windows API时,您将(而不是类型转换)转换为UTF-16并直接调用API的宽版本。这样可以在完成一些转换和一些临时缓冲的过程中为您提供完全保真度。由于这些类型的呼叫很少出现在热点,因此成本通常不是很大。

在Windows上,要在UTF-8和UTF-16之间进行转换,可以调用MultiByteToWideChar / WideCharToMultiByte,并将代码页设置为CP_UTF8。

答案 6 :(得分:0)

我已经挣扎了很长一段时间。经过相当多的挖掘后,我发现这种方法效果最好;你可以尝试以下方法:

{{1}}