c++ mfc cstring stdstring

c++ - ¿Cómo convertir CString y:: std:: string:: std:: wstring entre sí?



mfc stdstring (10)

CString es bastante útil, mientras que std::string es más compatible con el contenedor STL. Estoy usando hash_map . Sin embargo, hash_map no admite CString como clave, por lo que quiero convertir CString en std::string .

Escribir una función hash de CString parece tomar mucho tiempo.

CString -----> std::string

¿Cómo puedo hacer esto?

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

¿Estoy en lo cierto?

EDITAR:

Aquí hay más preguntas:

¿Cómo puedo convertir wstring , CString entre ellos?

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

Hay algun problema?

¿Cómo puedo convertir std::wstring , std::string entre sí?


¿Por qué no simplemente CStringA desde CString a CStringA dentro de un constructor de string ?

CString s1("SomeString"); string s2((CStringA)s1);


De acuerdo con CodeGuru :

CString a std::string :

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

PERO: std::string no siempre se puede construir desde un LPCTSTR . es decir, el código fallará para las construcciones UNICODE.

Como std::string solo puede construir desde LPSTR / LPCSTR , un programador que usa VC ++ 7.xo mejor puede utilizar clases de conversión como CT2CA como intermediario.

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 : (De las preguntas frecuentes de CString de Visual Studio ... )

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

CStringT puede construir tanto de cadenas de caracteres como de caracteres anchos. es decir, puede convertir de char* (es decir, LPSTR ) o de wchar_t* ( LPWSTR ).

En otras palabras, la especialización de caracteres (de CStringT ), es decir, CStringA , wchar_t -specilization CStringW y TCHAR -specialization CString se pueden construir a partir de caracteres char o de caracteres amplios, nulo terminado (la terminación nula es muy importante aquí) fuentes de cuerda
Althoug IInspectable modifica la parte de "terminación nula" en los comentarios :

NUL-terminación no es necesario .
CStringT tiene constructores de conversión que toman un argumento de longitud explícita. Esto también significa que puede construir objetos CStringT desde objetos std::string con caracteres NUL incrustados.


Es más eficiente convertir CString a std::string usando la conversión donde se especifica la longitud.

CString someStr("Hello how are you"); std::string std(somStr, someStr.GetLength());

En lazo cerrado, esto mejora significativamente el rendimiento.


Este es un seguimiento de la respuesta de Sal, donde proporcionó la solución:

CString someStr("Hello how are you"); std::string std(somStr, someStr.GetLength());

Esto también es útil al convertir un C-String no típico a std :: string

Un caso de uso para mí era tener una matriz de caracteres preasignada (como C-String), pero no está terminada en NUL. (es decir, resumen de SHA). La sintaxis anterior me permite especificar la longitud del resumen SHA de la matriz char para que std :: string no tenga que buscar el carácter terminante NUL, que puede estar o no allí.

Como:

unsigned char hashResult[SHA_DIGEST_LENGTH]; auto value = std::string(reinterpret_cast<char*>hashResult, SHA_DIGEST_LENGTH);


Esto funciona bien:

//Convert CString to std::string inline std::string to_string(const CString& cst) { return CT2A(cst.GetString()); }


Funciona para mi:

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


Resuelva eso usando std::basic_string<TCHAR> lugar de std::string y debería funcionar bien independientemente de la configuración de su carácter.


Si está buscando convertir fácilmente entre otros tipos de cadenas, ¿tal vez la clase _bstr_t sería más apropiada? Es compatible con la conversación entre char , wchar_t y BSTR .


Si quieres algo más similar a C ++, esto es lo que uso. Aunque depende de Boost, eso es solo por excepciones. Puede eliminar fácilmente aquellos que lo dejen para que dependan solo de la llamada a la API Win32 WideCharToMultiByte() STL.

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


Todas las demás respuestas no respondieron exactamente a lo que estaba buscando, que consistía en convertir CString sobre la marcha en lugar de almacenar el resultado en una variable.

La solución es similar a la anterior, pero necesitamos un paso más para crear un objeto sin nombre. Estoy ilustrando con un ejemplo. Aquí está mi función que necesita std::string pero tengo 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; }

¿Cómo llamarlo cuando tienes un CString ?

std::string firstName = "First"; CString lastName = _T("Last"); writeLog( firstName + ", " + std::string( CT2A( lastName ) ) );

Tenga en cuenta que la última línea no es un encasillado directo, pero estamos creando un objeto std::string sin nombre y suministramos el CString través de su constructor.