C++ 如何从 LPCTSTR 转换为 std::string?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5513718/
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-28 18:20:36  来源:igfitidea点击:

How do I convert from LPCTSTR to std::string?

c++stringvisual-c++

提问by GrahamS

I have an LPCTSTRand want to call a function that takes a std::stringparameter.

我有一个LPCTSTR并想调用一个带std::string参数的函数。

What conversion do I need to do?

我需要做什么转换?

回答by Jon

Tip of the iceberg

冰山一角

LPCTSTRcan be either a single-byte or a multibyte string (depends on the UNICODEconstant being defined during compilation or not), while std::string's users (including your function) normally use it to hold a single-byte string.

LPCTSTR可以是单字节或多字节字符串(取决于UNICODE编译期间定义的常量与否),而std::string的用户(包括您的函数)通常使用它来保存单字节字符串。

You 'd need two conversions: one for LPCSTR(non-UNICODEbuild) and one for LPCWSTR(UNICODEbuild). The first one is simple:

您需要两种转换:一种用于LPCSTR(非UNICODE构建)和一种用于LPCWSTRUNICODE构建)。第一个很简单:

std::string convert(LPCSTR str) {
    return std::string(str);
}

The second one needs its input parameter to be converted to another encoding first with WideCharToMultiByte. Do not be alarmed by the name, the result canbe a single-byte char string; that depends on the CodePageparameter. You will have to use a codepage for a single-byte encoding, such as CP_ACP.

第二个需要首先将其输入参数转换为另一种编码WideCharToMultiByte。不要被名字吓到,结果可以是一个单字节的char字符串;这取决于CodePage参数。您必须使用代码页进行单字节编码,例如CP_ACP.

Update: WideCharToMultiByteexample

更新:WideCharToMultiByte示例

Be aware that accurately converting to a single-byte encoding is technically impossible if the input string contains characters not existing in the target encoding's code page.Since you mention it's going to be for filesystem functions, if the file path contains such characters the conversion will not be 100% accurate and the subsequent function calls will fail.

请注意,如果输入字符串包含目标编码的代码页中不存在的字符,那么准确地转换为单字节编码在技术上是不可能的。由于您提到它将用于文件系统函数,如果文件路径包含此类字符,则转换将不会 100% 准确,后续函数调用将失败。

std::string MBFromW(LPCWSTR pwsz, UINT cp) {
    int cch = WideCharToMultiByte(cp, 0, pwsz, -1, 0, 0, NULL, NULL);

    char* psz = new char[cch];

    WideCharToMultiByte(cp, 0, pwsz, -1, psz, cch, NULL, NULL);

    std::string st(psz);
    delete[] psz;

   return st;
}

Caveat emptor:The example above is from some code I had lying around and is not production-grade quality. The one immediately obvious flaw is that it is not exception-safe. It might also kill all the nice purple unicorns. Use it only as an example.

警告:上面的例子来自我身边的一些代码,不是生产级质量。一个显而易见的缺陷是它不是异常安全的。它也可能杀死所有漂亮的紫色独角兽。仅将其用作示例

The full encoding hell

完整的编码地狱

The naked truth is that std::stringcan be used for multibyte encodings (such as UTF8) just fine -- you can even use it to hold wide-char strings, since it's just a binary-safe array of bytes at heart.

赤裸裸的事实是,它std::string可以很好地用于多字节编码(例如 UTF8)——您甚至可以用它来保存宽字符字符串,因为它本质上只是一个二进制安全的字节数组。

The problem is that the STL functions that apply to std::stringexpect its contents to be in a single-byte encoding, and they won't produce correct results if this is not true.

问题是STL 函数适用于std::string期望其内容为单字节编码,如果这不是真的,它们将不会产生正确的结果。

By extension, we don't know what your function that takes an std::stringparameter expects-- it might expect a string encoded in UTF-8. But "by convention", I 'm assuming it also wants a single-byte-encoded string.

通过扩展,我们不知道带std::string参数的函数期望什么——它可能期望以 UTF-8 编码的字符串。但是“按照惯例”,我假设它也需要一个单字节编码的字符串。

回答by Inverse

in one line:

在一行中:

std::string s = CT2A( lpctstr );

回答by MSalters

From your comment: "The function I am calling will take the std::string and use it as the filename when calling std::fstream::open()"

来自您的评论:“我正在调用的函数将采用 std::string 并在调用 std::fstream::open() 时将其用作文件名”

Well, that's wrong. The function really should take a tstring(defined as typedef std::basic_string<TCHAR> tstring). There are many Windows files whose name cannot be represented without Unicode. For instance, all files under \User\<myusername\My Documents\if <myUserName>contains a non-ANSI character (and you really don't want to tell your user that he has a bad name!)

嗯,这是错误的。该函数确实应该采用tstring( 定义为typedef std::basic_string<TCHAR> tstring)。有许多 Windows 文件的名称不能在没有 Unicode 的情况下表示。例如,\User\<myusername\My Documents\if下的所有文件都<myUserName>包含一个非 ANSI 字符(而且您真的不想告诉您的用户他的名字不好!)

But once you've changed to tstring, it just works. You still get the same std::fstreamobject.

但是一旦您更改为tstring,它就会起作用。你仍然得到相同的std::fstream对象。

回答by Collin Dauphinee

LPCTSTRis a Windows define that reads as something like 'long pointer to a const character-type string.' I'm not actually sure what the T stands for, but it has to do with the project's character set.

LPCTSTR是一个 Windows 定义,读作类似于“指向 const 字符类型字符串的长指针”。我实际上不确定 T 代表什么,但它与项目的字符集有关。

If your project is using the Unicode character set, this type is a const wchar_t*, which uses two bytes per character. If your project is using the multi-byte characters character set, this type is a const char*, which uses one byte per character.

如果您的项目使用 Unicode 字符集,则此类型为 a const wchar_t*,每个字符使用两个字节。如果您的项目使用多字节字符字符集,则此类型为const char*,每个字符使用一个字节。

Most likely your project's character set is Unicode, so LPCTSTRis a const wchar_t*. Since std::stringuses one byte per character, it can't hold this two byte per character string. std::wstringcan, however.

最有可能你的项目的字符集是Unicode,所以LPCTSTR是一个const wchar_t*。由于std::string每个字符使用一个字节,因此每个字符串不能容纳这两个字节。std::wstring不过可以。

If you need to convert the const wchar_t*to a const char*to allow it to be assigned to a string, you can use functions like wcstombsto do this. If you're including ATL (specifically atlconv.h) in your project, it provides macros to do this more easily:

如果您需要将 the 转换const wchar_t*为 aconst char*以允许将其分配给字符串,则可以使用类似的函数wcstombs来执行此操作。如果您在项目中包含 ATL(特别是atlconv.h),它会提供宏来更轻松地执行此操作:

USES_CONVERSION;
const wchar_t* = L"Wide string";
std::string str = W2A(value);

回答by sehe

Pragmatic approach:

务实的方法:

     LPCTSTR input;

     std::string s;

#ifdef UNICODE
     std::wstring w;
     w = input;
     s = std::string(w.begin(), w.end()); // magic here
#else
     s = input;
#endif

See other answers for excellent backgrounders!

查看优秀背景人员的其他答案!

回答by marchelbling

This snippet of code should do conversion from LPWSTR to char*/std::string

这段代码应该做从 LPWSTR 到 char*/std::string 的转换

LPWSTR input = L"whatever";
int cSize = WideCharToMultiByte (CP_ACP, 0, input, wcslen(input), NULL, 0, NULL, NULL);
std::string output(static_cast<size_t>(cSize), '
std::string input = "whatever";
//computing wchar size:
int wSize = MultiByteToWideChar (CP_ACP, 0, (LPCSTR) input.c_str (), -1, 0, 0);

//allocating memory for wchar:
LPWSTR output = new WCHAR[wSize];

//conversion from string to LPWSTR:
MultiByteToWideChar (CP_ACP, MB_PRECOMPOSED , (LPCSTR) input.c_str (), -1, output, wSize);
'); WideCharToMultiByte (CP_ACP, 0, input, wcslen(input), reinterpret_cast<char*>(&output[0]), cSize, NULL, NULL);

and this snippet should do conversion from single-byte std::string to LPWSTR

并且此代码段应该从单字节 std::string 转换为 LPWSTR

##代码##

回答by Buhake Sindi

I don't know if this solutionmight help you.

我不知道这个解决方案是否对你有帮助。