如何从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有关吗?我该如何解决这个问题?
答案 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,这意味着CreateDirectory
是CreateDirectoryW
的别名,宽字符版本。但是,程序中的文本使用ANSI进行编码。这意味着您的程序无法正确处理国际化。
编译器告诉您CreateDirectoryW
期望的文本编码与您提供的文本编码之间存在不匹配。确实,您可以调用CreateDirectoryA
来解决该不匹配问题,但这只会使根问题永久化,即您在程序中使用ANSI文本这一事实。
因此,最好的解决方案是将所有文本编码为Unicode。停止使用string
并开始使用wstring
。将path
更改为wstring
后再
CreateDirectory(path.c_str(),NULL);
是对的。
答案 4 :(得分:1)
请改用CreateDirectoryA
。 CreateDirectory
是一个扩展为CreateDirectoryA
或CreateDirectoryW
的宏,具体取决于构建配置;他们分别采用LPCSTR
和LPCWSTR
。如果您知道自己有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}}