13

新版本的典型问题是如何从 转换std::stringLPCTSTR.

从不同的 SO 帖子中阅读,我了解到我应该这样做:

CreateDirectory(path.c_str(),NULL);

而且编译器仍然给出错误,因为cannot convert from const char * to LPCTSTR.

我试过:

CreateDirectory((LPCTSTR)path.c_str(),NULL);

没有错误!

仍然调用创建的目录(在正确的位置):

D:\\something\\㩄ぜ弲久䅓余屓䱆彄湡敤屲䵉ⴱ㠶ⴰⵃㅇ㉜洰⵭就䥄牃獥汵獴촀췍췍췍췍췍췍췍﷍﷽꯽ꮫꮫꮫﺫﻮﻮ

这不是我想要的,你可以猜到......

那么我错过了什么?它与 UNICODE/ANSI 有关吗?我该如何解决这个问题?

4

7 回答 7

7

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

通过这样做:(LPCTSTR)path.c_str()您从原始字符串中获取两个字符并从中创建一个 unicode wchar_t 字母。这样你就得到了“中文”字符。

于 2013-05-23T10:12:11.667 回答
6

您的问题LPCTSTR是解决wchar_t*char*基于您的构建是否支持 unicode(设置了 unicode 标志)的事实。

要显式调用char*版本,请调用CreateDirectoryA().

于 2013-05-23T10:12:36.053 回答
6

当您尝试查找“(std::) string to LPCTSTR”时会弹出此问题

这是一种如何转换和传递std::stringLPCTSTR使用的方法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 或其他代码页,那么这只是隐藏了问题。

于 2015-03-09T20:32:03.320 回答
5

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

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

因此,最好的解决方案是开始将所有文本编码为 Unicode。停止使用string并开始使用wstring。一旦你改变pathwstring那时

CreateDirectory(path.c_str(),NULL);

是正确的。

于 2013-05-23T10:39:19.817 回答
1

改为使用CreateDirectoryA。是一个宏,可以根据构建配置CreateDirectory展开CreateDirectoryA或展开;CreateDirectoryW他们分别取LPCSTRLPCWSTR。如果您知道自己有一个LPCSTR(这就是c_str()给您的),请使用第一个。

于 2013-05-23T10:13:11.037 回答
1

其他解释是正确的:

CreateDirectory 与许多 Window API 一样,实际上是一个宏,可根据是否UNICODE定义扩展为“ANSI”或“Wide”版本。ANSI 版本有效地将单字节字符串转换为宽字符串,然后委托给宽字符串版本。

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

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

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

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

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

于 2015-03-09T21:56:15.193 回答
0

我已经为此苦苦挣扎了一段时间。经过相当多的挖掘,我发现这是最好的;您可以尝试以下方法:

std::string t = "xyz";
CA2T wt (t.c_str());     
于 2016-06-21T15:46:19.597 回答