문제

CString 꽤 편리합니다 std::string STL 컨테이너와 더 호환됩니다. 나는 사용 중입니다 hash_map. 하지만, hash_map 지원하지 않습니다 CString 키로 변환하고 싶습니다 CString ~ 안으로 std::string.

쓰기 a 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 서로에게?

도움이 되었습니까?

해결책

에 따르면 코드 구루:

CString 에게 std::string:

CString cs("Hello");
std::string s((LPCTSTR)cs);

하지만: std::string 항상 a에서 구성 할 수는 없습니다 LPCTSTR. 즉, 코드는 유니 코드 빌드에 실패합니다.

처럼 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 에게 CString: (에서 Visual Studio의 CString FAQ ...)

std::string s("Hello");
CString cs(s.c_str());

CStringT 문자 또는 넓은 특성 문자열 모두에서 구성 할 수 있습니다. 즉, 전환 할 수 있습니다 char* (즉 LPSTR) 또는에서 wchar_t* (LPWSTR).

다시 말해, 숯별화 (OF CStringT) 즉 CStringA, wchar_t-지정 CStringW, 그리고 TCHAR-전문화 CString 어느 쪽로부터 구성 될 수 있습니다 char 또는 넓은 특성, NULL이 종료되었습니다 (여기서는 Null-Termination이 매우 중요합니다) 문자열 소스.
Althoug iinspectible "null-termination"부분을 수정합니다 의견에서:

Nul-Termination이 필요하지 않습니다.
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 ++와 같은 것을 원한다면 이것이 제가 사용하는 것입니다. 부스트에 달려 있지만 예외를위한 것입니다. 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 CODE (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- 스트링을 std :: string으로 변환 할 때도 유용합니다.

저를위한 유스 케이스는 사전 배치 된 숯 어레이 (c-string과 같은)를 가지고 있었지만 NUL은 종료되지 않았습니다. (즉, 샤 다이제스트). 위의 구문을 통해 char 배열의 SHA 다이제스트 길이를 지정하여 std :: string이 종료 Nul char를 찾을 필요가 없도록 할 수 있습니다.

와 같은:

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());
}

이 게시물에서 (감사합니다 마크 랜섬 )

cstring을 문자열로 변환 (vc6)

나는 이것을 테스트했으며 잘 작동합니다.

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 생성자를 통해.

거기 있어요 어느 문제?

몇 가지 문제가 있습니다.

  • CString 템플릿 전문화입니다 Cstringt. 에 따라 베이스 타입 문자 유형을 설명하면 두 가지 구체적인 전문화가 있습니다. CStringA (사용 char) 그리고 CStringW (사용 wchar_t).
  • 하는 동안 wchar_t Windows에서는 UTF-16 인코딩 된 코드 유닛을 사용하는 데 유비쿼터스가 사용됩니다. char 모호합니다. 후자는 일반적으로 ANSI 인코딩 된 문자를 저장하지만 ASCII, UTF-8 또는 이진 데이터를 저장할 수도 있습니다.
  • 우리는 인코 인코딩 (또는 문자 유형)을 모릅니다. CString (이를 통해 제어됩니다 _UNICODE 전처리 기호), 질문을 모호하게 만듭니다. 우리는 또한 원하는 캐릭터 인코딩을 모릅니다 std::string.
  • 유니 코드와 ANSI 사이의 변환은 본질적으로 손실입니다. ANSI 인코딩은 유니 코드 문자 세트의 서브 세트만을 나타낼 수 있습니다.

이러한 문제를 해결하기 위해 wchar_t UTF-16 인코딩 된 코드 단위를 저장합니다 char UTF-8 옥트 시퀀스를 보유합니다. 이것이 소스 및 대상 문자열이 소스 또는 대상 도메인의 서브 세트에 대한 솔루션을 제한하지 않고 동일한 정보를 유지하도록하기 위해 할 수있는 유일한 합리적인 선택입니다.

다음 구현은간에 변환됩니다 CStringA/CStringW 그리고 std::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 };
}

나머지 두 함수는 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() };
}

당신이 사용할 수있는 CT2CA

CString datasetPath;
CT2CA st(datasetPath);
string dataset(st);

다른 문자열 유형으로 쉽게 변환하려는 경우 _bstr_t 수업이 더 적절할까요? 그것은 사이의 대화를 지원합니다 char, wchar_t 그리고 BSTR.

흥미로운 접근법 중 하나는 캐스팅하는 것입니다 CString 에게 CStringA 내부 a string 건설자. 같지 않은 std::string s((LPCTSTR)cs); 이것은더라도 작동합니다 _UNICODE 정의됩니다. 그러나이 경우 유니 코드에서 ANSI로 변환을 수행하므로 ASCII 문자 세트를 넘어서 높은 유니 코드 값에 대해 안전하지 않습니다. 그러한 전환은 다음과 같습니다 _CSTRING_DISABLE_NARROW_WIDE_CONVERSION 사전 처리기 정의. https://msdn.microsoft.com/en-us/library/5bzxfsea.aspx

        CString s1("SomeString");
        string s2((CStringA)s1);
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top