C++ std::string 到 LPCTSTR

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16711124/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 20:34:42  来源:igfitidea点击:

std::string to LPCTSTR

c++windowsstring

提问by Ander Biguri

New version of the typical question of how to convert from std::stringto LPCTSTR.

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

Reading from different SO posts I learnt that I should do this:

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

CreateDirectory(path.c_str(),NULL);

And still the compiler gives error because cannot convert from const char * to LPCTSTR.

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

I tried:

我试过:

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

No errors!

没有错误!

Still the directory created (in the correct place) is called:

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

D:\something\?ぜ弲久?余屓?彄湡敤屲???????洰?就?牃獥汵獴?????????????????

which is not exactly what I wanted, as you can guess...

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

So what am I missing? Is it something related with UNICODE/ANSI? How can I resolve this?

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

采纳答案by Mario

Your problem here is the fact that LPCTSTRis resolved to wchar_t*or char*based on whether your build supports unicode (unicode flag set or not).

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

To explicitly call the char*version, call CreateDirectoryA().

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

回答by Martin Perry

Try to look at this page: What-are-TCHAR-WCHAR-LPSTR-LPWSTR-LPCTSTR-etc. If you are using MSVC, than you may have set Unicode for project and LPCSTRis "translated" to const wchar_t *, which is not compatible with const char *

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

By doing this: (LPCTSTR)path.c_str()you are taking two chars from original string and create from them one unicode wchar_t letter. Thats way you are getting "chinese" characters.

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

回答by jave.web

As this question pops up when you try to find "(std::) string to LPCTSTR"

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

Here's a way how to convert&pass std::stringas LPCTSTRusing wstring

这是一种如何转换和传递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);

IMPORTANT Noteby Adrian McCarthy:

重要说明阿德里安·麦卡锡

This is fine if the source string is ASCII or if it's ANSI and the current code page is Windows-1252 (which is very similar to Latin-1). If the source is UTF-8 or another code page, then this just hides the problem.

如果源字符串是 ASCII 或 ANSI 并且当前代码页是 Windows-1252(与 Latin-1 非常相似),这很好。如果源是 UTF-8 或其他代码页,那么这只是隐藏了问题。

回答by David Heffernan

You are compiling for Unicode which means that CreateDirectoryis an alias for CreateDirectoryW, the wide character version. However, the text in your program is encoded using ANSI. This means that your program cannot handle internationalization properly.

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

The compiler is telling you that there is a mismatch between the text encoding that CreateDirectoryWexpects, and the text encoding that you are supplying. It's true that you could call CreateDirectoryAto resolve that mis-match, but that is only going to perpetuate the root problem, the fact that you are using ANSI text in your program.

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

So, the best solution is to start encoding all your text as Unicode. Stop using stringand start using wstring. Once you change pathto wstringthen

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

CreateDirectory(path.c_str(),NULL);

is correct.

是正确的。

回答by Adrian McCarthy

The other explanations are correct:

其他解释是正确的:

CreateDirectory, like many of the Window APIs, is actually a macro that expands to an "ANSI" or "Wide" version depending on whether UNICODEis defined. The ANSI version effectively converts the single-byte character string to a wide character string and then delegates to the wide character string version.

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

However, the suggestions to call CreateDirectoryA directly come with some drawbacks:

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

The conversions done by the "ANSI" APIs assume that the source string is encoded in the user's current code page. In simple cases, this is likely true. But in lots of real-life code, it's not. So you can end up with the wrong type of conversion, which leads to bugs you'll find much later. At least the bad typecast leads to bugs you find immediately.

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

A better solution is to use wide strings (std::wstring) throughout, and to call CreateDirectoryW. No conversion to go wrong. No typecasts required.

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

For many code bases, rewriting everything to use wide strings is not practical. It turns out that there are good reasons to do exactly the opposite and to continue to use std::strings but to standardize on having them hold UTF-8 text. Then, when you have to call a Windows API, you convert (not typecast) to UTF-16 and call the wide version of the API directly. That gives you full fidelity at the cost of a doing a few conversions and some temporary buffers. Since these types of calls are rarely in hot spots, the cost isn't usually a big deal.

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

On Windows, to convert between UTF-8 and UTF-16, you can call MultiByteToWideChar/WideCharToMultiByte with the code page set to CP_UTF8.

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

回答by slaphappy

Use CreateDirectoryAinstead. CreateDirectoryis a macro that expands to either CreateDirectoryAor CreateDirectoryWdepending on the build configuration; They take respectively LPCSTRand LPCWSTR. If you know you have a LPCSTR(which is what c_str()gives you), use the first one.

使用CreateDirectoryA来代替。CreateDirectory是一个宏,可扩展为CreateDirectoryACreateDirectoryW取决于构建配置;他们分别取LPCSTRLPCWSTR。如果你知道你有一个LPCSTR(这是c_str()给你的),使用第一个。

回答by Sarthak Bansal

I have struggled with this for quite a while. After quite a bit of digging I found this works the best; you could try the following:

我已经为此挣扎了很长一段时间。经过一番挖掘,我发现这是最好的;您可以尝试以下操作:

std::string t = "xyz";
CA2T wt (t.c_str());