views:

13146

answers:

4

CString is quit handy, while std::string is more compatible with stl container. I am using hash_map, however, hash_map does not support CString as key, so I wish I could convert CString into std::string, is it possible?

Write a CString hash function seems take lots of time.

CString ------> std::string ? how can I do?

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

inline CString toCString(std::string const& str)
{
     return CString(str.c_str()); 
}

Am I right?

VonC's method work! I wish anyone with the same problem can get help from his solution. Thank VonC very much!

Here are more Questions: How to Convert wstring, CString to each other?

//wstring -> CString,
std::wstring src;
CString result(src.c_str());
//CString->wstring. 
CString src;
::std::wstring des(src.GetString());

Are there any problem?

how to convert wstring, string to each other?

+11  A: 

According to CodeGuru:

'CString' to 'std::string':

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

BUT: std::string cannot always construct from a LPCTSTR i.e. the code will fail for UNICODE builds.

As std::string can construct only from LPSTR / LPCSTR, a programmer who uses VC++ 7.x or better can utilize conversion classes such as CT2CA as an intermediary.

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': (From Visual Studio's CString FAQs...)

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

CStringT can construct from both character or wide-character strings. i.e. It can convert from char* (i.e. LPSTR) or from wchar_t* (LPWSTR).

In other words, char-specialization (of CStringT) i.e. CStringA, wchar_t-specilization CStringW, and TCHAR-specialization CString can be constructed from either char or wide-character, null terminated (null-termination is very important here) string sources.

VonC
OMG, YOU ARE CODE KING!Thanks~!!!!!!!!!!!!!!!!!!!!
Errr... you are welcome :) Thanks to Siddhartha Rao for the detailed explanations.
VonC
+9  A: 

Solve that by using std::basic_string<TCHAR> instead of std::string and it should work fine regardless of your character setting.

OJ
This method is more simple
A: 

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.

OJ
+2  A: 

If you want something more purely C++, this is what I use. Although it depends on Boost, that's just for exceptions. You can easily remove those leaving it to depend only on the STL and the WideCharToMultiByte() Win32 API call.

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

I would greatly appreciate any comments or improvements you have!

thehouse