CString과 :: std :: string :: std :: wstring을 서로 변환하는 방법은 무엇입니까?
CString매우 편리하지만 std::stringSTL 컨테이너와 더 호환됩니다. 나는 hash_map. 그러나 hash_map지원하지 않습니다 CStringI 변환 할 수 있도록, 키로 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에서만 구성 할 수 있기 때문에 VC ++ 7.x 이상을 사용하는 프로그래머 는 중개자 와 같은 변환 클래스를 활용할 수 있습니다 .LPSTRLPCSTRCT2CA
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::stringtoCString : ( Visual Studio의 CString FAQ에서 ... )
std::string s("Hello");
CString cs(s.c_str());
CStringT문자 또는 와이드 문자열 모두에서 구성 할 수 있습니다. 즉, char*(예 LPSTR) 또는 wchar_t*( LPWSTR) 에서 변환 할 수 있습니다 .
즉, (의 숯불 전문화 CStringT) 즉 CStringA, wchar_t-specilization CStringW및 TCHAR-specialization이 CString중 구성 될 수 있습니다 char또는 와이드 문자,null 종료 (null 종료는 여기서 매우 중요합니다)문자열 소스.
대체 IInspectable 은 주석 의 "null-termination"부분 을 수정합니다 .
NUL 종료는 필요하지 않습니다 .
CStringT명시적인 길이 인수를 취하는 변환 생성자가 있습니다. 이는 또한 문자 가 포함 된CStringT개체에서std::string개체를 구성 할 수 있음을 의미합니다NUL.
std::basic_string<TCHAR>대신 사용하여 해결하면 std::string캐릭터 설정에 관계없이 잘 작동합니다.
길이가 지정된 변환 CString을 std::string사용하여 변환하는 것이 더 효율적 입니다.
CString someStr("Hello how are you");
std::string std(somStr, someStr.GetLength());
타이트 루프에서 이것은 상당한 성능 향상을 가져옵니다.
좀 더 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);
}
(VS2012 이후 ... 그리고 적어도 VS2017 v15.8.1까지)
MFC 프로젝트이고 CString은 MFC 클래스이므로 MS는 기술 노트 TN059 : MFC MBCS / 유니 코드 변환 매크로 및 일반 변환 매크로 사용 :
A2CW (LPCSTR) -> (LPCWSTR)
A2W (LPCSTR) -> (LPWSTR)
W2CA (LPCWSTR) -> (LPCSTR)
W2A (LPCWSTR) -> (LPSTR)
사용하다:
void Example() // ** UNICODE case **
{
USES_CONVERSION; // (1)
// CString to std::string / std::wstring
CString strMfc{ "Test" }; // strMfc = L"Test"
std::string strStd = W2A(strMfc); // ** Conversion Macro: strStd = "Test" **
std::wstring wstrStd = strMfc.GetString(); // wsrStd = L"Test"
// std::string to CString / std::wstring
strStd = "Test 2";
strMfc = strStd.c_str(); // strMfc = L"Test 2"
wstrStd = A2W(strStd.c_str()); // ** Conversion Macro: wstrStd = L"Test 2" **
// std::wstring to CString / std::string
wstrStd = L"Test 3";
strMfc = wstrStd.c_str(); // strMfc = L"Test 3"
strStd = W2A(wstrStd.c_str()); // ** Conversion Macro: strStd = "Test 3" **
}
-
각주 :
(1) 변환 매크로가 임시 길이를 저장할 공간을 갖기 위해서는 _convert변환 매크로를 사용하는 각 함수에서이를 수행 하는 로컬 변수를 선언해야 합니다. 이것은 USES_CONVERSION매크로 를 호출하여 수행됩니다 . VS2017 MFC 코드 (atlconv.h)에서는 다음과 같습니다.
#ifndef _DEBUG
#define USES_CONVERSION int _convert; (_convert); UINT _acp = ATL::_AtlGetConversionACP() /*CP_THREAD_ACP*/; (_acp); LPCWSTR _lpw; (_lpw); LPCSTR _lpa; (_lpa)
#else
#define USES_CONVERSION int _convert = 0; (_convert); UINT _acp = ATL::_AtlGetConversionACP() /*CP_THREAD_ACP*/; (_acp); LPCWSTR _lpw = NULL; (_lpw); LPCSTR _lpa = NULL; (_lpa)
#endif
이것은 Sal의 답변에 대한 후속 조치이며, 그가 솔루션을 제공했습니다.
CString someStr("Hello how are you");
std::string std(somStr, someStr.GetLength());
이것은 일반적이지 않은 C-String을 std :: string으로 변환 할 때도 유용합니다.
나를위한 유스 케이스는 미리 할당 된 char 배열 (예 : C-String)을 가지고 있었지만 NUL로 끝나지 않았습니다. (즉, SHA 다이제스트). 위의 구문을 사용하면 std :: string이 종료 NUL 문자를 찾을 필요가 없도록 char 배열의 SHA 다이제스트 길이를 지정할 수 있습니다.
예 :
unsigned char hashResult[SHA_DIGEST_LENGTH];
auto value = std::string(reinterpret_cast<char*>hashResult, SHA_DIGEST_LENGTH);
이것은 잘 작동합니다.
//Convert CString to std::string
inline std::string to_string(const CString& cst)
{
return CT2A(cst.GetString());
}
이 게시물에서 (감사합니다 Mark Ransom )
나는 이것을 테스트했고 잘 작동합니다.
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결과를 변수에 저장하는 것과는 달리 즉시 변환하는 것이 뭘 찾고 있었는지 제대로 다루지 않았습니다 .
The solution is similar to above but we need one more step to instantiate a nameless object. I am illustrating with an example. Here is my function which needs std::string but I have 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;
}
How to call it when you have a CString?
std::string firstName = "First";
CString lastName = _T("Last");
writeLog( firstName + ", " + std::string( CT2A( lastName ) ) );
Note that the last line is not a direct typecast but we are creating a nameless std::string object and supply the CString via its constructor.
Is there any problem?
There are several issues:
CStringis a template specialization of CStringT. Depending on the BaseType describing the character type, there are two concrete specializations:CStringA(usingchar) andCStringW(usingwchar_t).- While
wchar_ton Windows is ubiquitously used to store UTF-16 encoded code units, usingcharis ambiguous. The latter commonly stores ANSI encoded characters, but can also store ASCII, UTF-8, or even binary data. - We don't know the character encoding (or even character type) of
CString(which is controlled through the_UNICODEpreprocessor symbol), making the question ambiguous. We also don't know the desired character encoding ofstd::string. - Converting between Unicode and ANSI is inherently lossy: ANSI encoding can only represent a subset of the Unicode character set.
To address these issues, I'm going to assume that wchar_t will store UTF-16 encoded code units, and char will hold UTF-8 octet sequences. That's the only reasonable choice you can make to ensure that source and destination strings retain the same information, without limiting the solution to a subset of the source or destination domains.
The following implementations convert between CStringA/CStringW and std::wstring/std::string mapping from UTF-8 to UTF-16 and vice versa:
#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 };
}
The remaining two functions construct C++ string objects from MFC strings, leaving the encoding unchanged. Note that while the previous functions cannot cope with embedded NUL characters, these functions are immune to that.
#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() };
}
You can use CT2CA
CString datasetPath;
CT2CA st(datasetPath);
string dataset(st);
If you're looking to convert easily between other strings types, perhaps the _bstr_t class would be more appropriate? It supports converstion between char, wchar_t and BSTR.
One interesting approach is to cast CString to CStringA inside a string constructor. Unlike std::string s((LPCTSTR)cs); this will work even if _UNICODE is defined. However, if that is the case, this will perform conversion from Unicode to ANSI, so it is unsafe for higher Unicode values beyond the ASCII character set. Such conversion is subject to the _CSTRING_DISABLE_NARROW_WIDE_CONVERSION preprocessor definition. https://msdn.microsoft.com/en-us/library/5bzxfsea.aspx
CString s1("SomeString");
string s2((CStringA)s1);
'Nice programing' 카테고리의 다른 글
| npm을 사용하여 "devDependencies"만 설치하는 방법 (0) | 2020.11.04 |
|---|---|
| 이름이 [DEFAULT] 인 FirebaseApp이 존재하지 않습니다. (0) | 2020.11.04 |
| Python urllib2 : HTTPError 예외 중에도 콘텐츠 본문을 읽습니까? (0) | 2020.11.04 |
| ConcurrentMap의 putIfAbsent를 사용하기 전에 맵에 키가 포함되어 있는지 확인해야합니다. (0) | 2020.11.04 |
| 자바 스크립트 코드를 통해 체크 된 경우에도 체크 박스 클릭 이벤트를 트리거하는 방법은 무엇입니까? (0) | 2020.11.04 |