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

2021-12-22 00:00:00 string visual-c++ c++

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

I have an LPCTSTR and want to call a function that takes a std::string parameter.

我需要做什么转换?

推荐答案

冰山一角

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

Tip of the iceberg

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

您需要两种转换:一种用于 LPCSTR(非UNICODE 构建),另一种用于 LPCWSTR(UNICODE构建).第一个很简单:

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

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

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

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 can be a single-byte char string; that depends on the CodePage parameter. You will have to use a codepage for a single-byte encoding, such as CP_ACP.

更新:WideCharToMultiByte 示例

Update: WideCharToMultiByte example

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

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.

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.

赤裸裸的事实是 std::string 可以用于多字节编码(例如 UTF8)就好了――你甚至可以用它来保存宽字符字符串,因为它只是一个二进制安全的字节数组.

The naked truth is that std::string can 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 的 STL 函数期望其内容采用单字节编码,并且它们不会产生正确的如果这不是真的,则结果.

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

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

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

相关文章