如何将CString和:: std :: string :: std :: wstring互相转换?

use*_*749 69 c++ mfc cstring stdstring

CString非常方便,同时std::string与STL容器更兼容.我在用hash_map.但是,hash_map不支持CString作为键,所以我想转换CStringstd::string.

编写CString哈希函数似乎需要花费很多时间.

CString -----> std::string
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?

std::string -----> CString:

inline CString toCString(std::string const& str)
{
    return CString(str.c_str()); 
}
Run Code Online (Sandbox Code Playgroud)

我对吗?


编辑:

以下是更多问题:

我怎么能转换wstring,CString彼此?

//wstring -> CString,
std::wstring src;
CString result(src.c_str());
//CString->wstring. 
CString src;
::std::wstring des(src.GetString());
Run Code Online (Sandbox Code Playgroud)

什么问题吗?

我怎么能转换std::wstring,std::string彼此?

Von*_*onC 87

根据CodeGuru:

CStringstd::string:

CString cs("Hello");
std::string s((LPCTSTR)cs);
Run Code Online (Sandbox Code Playgroud)

但是: std::string不能总是从一个构造LPCTSTR.即UNICODE版本的代码将失败.

由于std::string只能从LPSTR/ 构造LPCSTR,使用VC++ 7.x或更高版本的程序员可以使用转换类,例如作为CT2CA中介.

CString cs ("Hello");
// Convert a TCHAR string to a LPCSTR
CT2CA pszConvertedAnsiString (cs);
// construct a std::string using the LPCSTR input
std::string strStd (pszConvertedAnsiString);
Run Code Online (Sandbox Code Playgroud)

std::stringtoCString :(来自Visual Studio的CString常见问题解答......)

std::string s("Hello");
CString cs(s.c_str());
Run Code Online (Sandbox Code Playgroud)

CStringT可以从字符或宽字符串构造.即它可以从char*(即LPSTR)或从wchar_t*(LPWSTR)转换.

换句话说,炭专业化(的CStringT),即CStringA,wchar_t-specilization CStringWTCHAR-specialization CString可以从任一构造char或宽字符,null终止(null终止在这里非常重要)字符串来源.
Althoug IInspectable修订了"空终止"部分中的评论:

不需要NUL终止.
CStringT具有采用显式长度参数的转换构造函数.这也意味着您可以CStringTstd::string具有嵌入NUL字符的对象构造对象.

  • 呃...欢迎你:)感谢Siddhartha Rao的详细解释. (2认同)

OJ.*_*OJ. 34

通过使用std::basic_string<TCHAR>而不是std::string你的角色解决它,它应该工作正常,无论你的角色设置.

  • 为了方便和熟悉,我喜欢键入dede:`typedef std :: basic_string <TCHAR> tstring` (5认同)
  • 这种方法更简单 (2认同)

the*_*use 5

如果你想要更像 C++ 的东西,这就是我使用的。虽然它依赖于 Boost,但这只是例外。您可以轻松删除那些使其仅依赖于 STL 和WideCharToMultiByte()Win32 API 调用的内容。

#include <string>
#include <vector>
#include <cassert>
#include <exception>

#include <boost/system/system_error.hpp>
#include <boost/integer_traits.hpp>

/**
 * Convert a Windows wide string to a UTF-8 (multi-byte) string.
 */
std::string WideStringToUtf8String(const std::wstring& wide)
{
    if (wide.size() > boost::integer_traits<int>::const_max)
        throw std::length_error(
            "Wide string cannot be more than INT_MAX characters long.");
    if (wide.size() == 0)
        return "";

    // Calculate necessary buffer size
    int len = ::WideCharToMultiByte(
        CP_UTF8, 0, wide.c_str(), static_cast<int>(wide.size()), 
        NULL, 0, NULL, NULL);

    // Perform actual conversion
    if (len > 0)
    {
        std::vector<char> buffer(len);
        len = ::WideCharToMultiByte(
            CP_UTF8, 0, wide.c_str(), static_cast<int>(wide.size()),
            &buffer[0], static_cast<int>(buffer.size()), NULL, NULL);
        if (len > 0)
        {
            assert(len == static_cast<int>(buffer.size()));
            return std::string(&buffer[0], buffer.size());
        }
    }

    throw boost::system::system_error(
        ::GetLastError(), boost::system::system_category);
}
Run Code Online (Sandbox Code Playgroud)


Sal*_*Sal 5

转换CStringstd::string使用指定长度的转换更有效.

CString someStr("Hello how are you");
std::string std(somStr, someStr.GetLength());
Run Code Online (Sandbox Code Playgroud)

在紧密循环中,这可以显着提高性能.

  • 我使用此错误:`无法将参数1从'CString'转换为'const std :: basic_string &lt;_Elem,_Traits,_Alloc&gt;&' (2认同)

IIn*_*ble 5

什么问题吗?

有几个问题:

  • CString是CStringT的模板特化。根据描述字符类型的BaseType,有两种具体的特化:CStringA(using char) 和CStringW(using wchar_t)。
  • 虽然wchar_t在 Windows 上普遍用于存储 UTF-16 编码的代码单元,但使用char是不明确的。后者通常存储 ANSI 编码字符,但也可以存储 ASCII、UTF-8 甚至二进制数据。
  • 我们不知道CString(通过预处理器符号控制_UNICODE)的字符编码(甚至字符类型),使得问题含糊不清。我们也不知道所需的字符编码std::string
  • Unicode 和 ANSI 之间的转换本质上是有损的:ANSI 编码只能表示 Unicode 字符集的子集。

为了解决这些问题,我假设wchar_t将存储 UTF-16 编码的代码单元,并将char保存 UTF-8 八位字节序列。这是您可以做出的唯一合理选择,以确保源字符串和目标字符串保留相同的信息,而不会将解决方案限制为源域或目标域的子集。

以下实现在CStringA/CStringWstd::wstring/std::string映射之间进行从 UTF-8 到 UTF-16 的转换,反之亦然:

#include <string>
#include <atlconv.h>

std::string to_utf8(CStringW const& src_utf16)
{
    return { CW2A(src_utf16.GetString(), CP_UTF8).m_psz };
}

std::wstring to_utf16(CStringA const& src_utf8)
{
    return { CA2W(src_utf8.GetString(), CP_UTF8).m_psz };
}
Run Code Online (Sandbox Code Playgroud)

其余两个函数从 MFC 字符串构造 C++ 字符串对象,保持编码不变。请注意,虽然前面的函数无法处理嵌入的 NUL 字符,但这些函数却不受此影响。

#include <string>
#include <atlconv.h>

std::string to_std_string(CStringA const& src)
{
    return { src.GetString(), src.GetString() + src.GetLength() };
}

std::wstring to_std_wstring(CStringW const& src)
{
    return { src.GetString(), src.GetString() + src.GetLength() };
}
Run Code Online (Sandbox Code Playgroud)