如何将CString和:: std :: string :: std :: wstring互相转换?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何将CString和:: std :: string :: std :: wstring互相转换?相关的知识,希望对你有一定的参考价值。
CString
非常方便,而std::string
与STL容器更兼容。我正在使用hash_map
。然而,hash_map
不支持CString
作为关键,所以我想将CString
转换为std::string
。
编写CString
哈希函数似乎需要花费很多时间。
CString -----> std::string
我怎样才能做到这一点?
std::string -----> CString:
inline CString toCString(std::string const& str)
{
return CString(str.c_str());
}
我对吗?
编辑:
以下是更多问题:
我如何将wstring
,CString
互相转换?
//wstring -> CString,
std::wstring src;
CString result(src.c_str());
//CString->wstring.
CString src;
::std::wstring des(src.GetString());
有什么问题吗?
我如何将std::wstring
,std::string
互相转换?
据CodeGuru说:
CString
到std::string
:
CString cs("Hello");
std::string s((LPCTSTR)cs);
但是: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);
std::string
to CString
:(来自Visual Studio's CString FAQs...)
std::string s("Hello");
CString cs(s.c_str());
CStringT
可以从字符或宽字符串构造。即它可以从char*
(即LPSTR
)或wchar_t*
(LPWSTR
)转换。
换句话说,char-specialization(CStringT
)即CStringA
,wchar_t
-specilization CStringW
和TCHAR
-specialization CString
可以用char
或宽字符构建,
null终止(null终止在这里非常重要)
字符串来源。
Althoug IInspectable修改了“无效终止”部分in the comments:
不需要NUL终止。
CStringT
具有转换构造函数,它采用显式长度参数。这也意味着您可以使用嵌入的CStringT
字符从std::string
对象构造NUL
对象。
所有其他答案并没有完全解决我正在寻找的是在运行中转换std::string Utils::CString2String(const CString& cString)
{
std::string strStd;
for (int i = 0; i < cString.GetLength(); ++i)
{
if (cString[i] <= 0x7f)
strStd.append(1, static_cast<char>(cString[i]));
else
strStd.append(1, '?');
}
return strStd;
}
而不是将结果存储在变量中。
解决方案与上面的类似,但我们还需要一个步骤来实例化无名对象。我用一个例子来说明。这是我的功能需要std::wstring CStringToWString(const CString& s)
{
std::string s2;
s2 = std::string((LPCTSTR)s);
return std::wstring(s2.begin(),s2.end());
}
CString WStringToCString(std::wstring s)
{
std::string s2;
s2 = std::string(s.begin(),s.end());
return s2.c_str();
}
但我有CString
。
std::string
如果你有CString
怎么称呼它?
void CStringsPlayDlg::writeLog(const std::string &text)
{
std::string filename = "c:\test\test.txt";
std::ofstream log_file(filename.c_str(), std::ios_base::out | std::ios_base::app);
log_file << text << std::endl;
}
请注意,最后一行不是直接类型转换,但我们正在创建一个无名的CString
对象,并通过其构造函数提供std::string firstName = "First";
CString lastName = _T("Last");
writeLog( firstName + ", " + std::string( CT2A( lastName ) ) );
。
有什么问题吗?
有几个问题:
std::string
是CString
的模板专业化。根据描述字符类型的BaseType,有两个具体的特化:CString
(使用CStringT)和CStringA
(使用char
)。- 虽然Windows上的
CStringW
无处不在用于存储UTF-16编码的代码单元,但使用wchar_t
是不明确的。后者通常存储ANSI编码字符,但也可以存储ASCII,UTF-8甚至二进制数据。 - 我们不知道
wchar_t
(通过char
预处理器符号控制)的字符编码(甚至字符类型),使问题模糊不清。我们也不知道CString
所需的字符编码。 - 在Unicode和ANSI之间进行转换本质上是有损的:ANSI编码只能表示Unicode字符集的子集。
为了解决这些问题,我将假设_UNICODE
将存储UTF-16编码的代码单元,而std::string
将保存UTF-8八位字节序列。这是确保源和目标字符串保留相同信息的唯一合理选择,而不会将解决方案限制为源域或目标域的子集。
以下实现在wchar_t
/ char
和CStringA
/ CStringW
之间转换,从UTF-8到UTF-16,反之亦然:
std::wstring
其余两个函数从MFC字符串构造C ++字符串对象,保持编码不变。请注意,虽然以前的函数无法处理嵌入的NUL字符,但这些函数不受此影响。
std::string
您可以使用CT2CA
#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 };
}
如果你想在其他字符串类型之间轻松转换,也许#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() };
}
类更合适?它支持CString datasetPath;
CT2CA st(datasetPath);
string dataset(st);
,_bstr_t
和char
之间的转换。
一个有趣的方法是在wchar_t
构造函数中将BSTR
投射到CString
。与CStringA
不同,即使定义了string
,这也会起作用。但是,如果是这种情况,这将执行从Unicode到ANSI的转换,因此对于ASCII字符集之外的更高Unicode值不安全。这种转换受std::string s((LPCTSTR)cs);
预处理器定义的约束。 _UNICODE
_CSTRING_DISABLE_NARROW_WIDE_CONVERSION
通过使用std::basic_string<TCHAR>
而不是std::string
来解决这个问题,无论你的角色设置如何,它都可以正常工作。
使用指定长度的转换将qazxsw poi转换为qazxsw poi更有效。
CString
在紧密循环中,这可以显着提高性能。
如果你想要更多类似C ++的东西,这就是我使用的东西。虽然它取决于Boost,但这仅仅是例外。您可以轻松删除那些只依赖于STL和std::string
Win32 API调用的文件。
CString someStr("Hello how are you");
std::string std(somStr, someStr.GetLength());
(自VS2012以来......至少在VS2017 v15.8.1之前)
由于它是一个MFC项目而CString是一个MFC类,因此MS提供了技术说明WideCharToMultiByte()
和通用转换宏:
#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);
}以上是关于如何将CString和:: std :: string :: std :: wstring互相转换?的主要内容,如果未能解决你的问题,请参考以下文章
如何知道 std::string/Cstring 中的值是不是为数字
如何将 MFC CString 与 boost 字符串算法库一起使用
如何从字符串位置构造 CString/std::string