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 objetosCStringT
desde objetosstd::string
con caracteresNUL
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.