CString
est assez pratique, alors que std::string
est plus compatible avec le conteneur STL . J'utilise hash_map
. Cependant, hash_map
ne supporte pas CString
en tant que clé, je souhaite donc convertir CString
en std::string
.
Écrire une fonction de hachage CString
semble prendre beaucoup de temps.
CString -----> std::string
Comment puis-je faire ceci?
std::string -----> CString:
inline CString toCString(std::string const& str)
{
return CString(str.c_str());
}
Ai-je raison?
EDIT:
Voici d'autres questions:
Comment puis-je convertir wstring
, CString
les uns aux autres?
//wstring -> CString,
std::wstring src;
CString result(src.c_str());
//CString->wstring.
CString src;
::std::wstring des(src.GetString());
Existe-t-il un problème?
Comment puis-je convertir std::wstring
, std::string
l'un à l'autre?
Selon CodeGuru :
CString
à std::string
:
CString cs("Hello");
std::string s((LPCTSTR)cs);
BUT:std::string
ne peut pas toujours construire à partir d'une LPCTSTR
. c'est-à-dire que le code échouera pour les générations UNICODE.
Comme std::string
ne peut construire que à partir de LPSTR
LPCSTR
, un programmeur qui utilise VC++ 7.x ou une version supérieure peut utiliser des classes de conversion telles que CT2CA
en tant qu'intermédiaire.
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
: (De FAQ CString de Visual Studio ... )
std::string s("Hello");
CString cs(s.c_str());
CStringT
peut construire à partir de chaînes de caractères ou de chaînes de caractères larges. il peut convertir à partir de char*
(i.e. LPSTR
) ou de wchar_t*
(LPWSTR
).
En d'autres termes, la spécialisation sur caractères (de CStringT
), c'est-à-dire CStringA
, wchar_t
- specilization CStringW
, et TCHAR
- specialization CString
peut être construite à partir de char
ou de caractères larges, null terminé (la terminaison nulle est très importante ici) sources de chaîne.
Althoug Non respectable modifie la partie "null-termination" dans les commentaires :
_/NUL-terminaison n'est pas nécessaire.
CStringT
a des constructeurs de conversion qui prennent un argument de longueur explicite. Cela signifie également que vous pouvez construire des objetsCStringT
à partir d'objetsstd::string
avec des caractèresNUL
incorporés.
Résolvez cela en utilisant std::basic_string<TCHAR>
au lieu de std::string
et tout devrait bien se passer, quel que soit le réglage de votre personnage.
Il est plus efficace de convertir CString
en std::string
en utilisant la conversion où la longueur est spécifiée.
CString someStr("Hello how are you");
std::string std(somStr, someStr.GetLength());
En boucle serrée, cela améliore considérablement les performances.
Si vous voulez quelque chose de plus C++, c'est ce que j'utilise. Bien que cela dépende de Boost, ce n'est que des exceptions. Vous pouvez facilement supprimer ceux qui le laissent pour qu'ils ne dépendent que de la STL et de l'appel API Win32 WideCharToMultiByte()
.
#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);
}
Ceci est un suivi de la réponse de Sal, où il/elle a fourni la solution:
CString someStr("Hello how are you");
std::string std(somStr, someStr.GetLength());
Ceci est utile également lors de la conversion d'une chaîne de caractères non typique en une chaîne std :: string
Un cas d'utilisation pour moi était d'avoir un tableau de caractères pré-alloué (comme C-String), mais il n'est pas terminé par NUL. (c'est-à-dire SHA digest) .. ... La syntaxe ci-dessus me permet de spécifier la longueur du résumé SHA du tableau de caractères afin que std :: string ne doive pas rechercher le NUL final char, qui peut ou peut ne pas être là.
Tel que:
unsigned char hashResult[SHA_DIGEST_LENGTH];
auto value = std::string(reinterpret_cast<char*>hashResult, SHA_DIGEST_LENGTH);
de ce post (Merci Mark Ransom )
Convertit CString en chaîne (VC6)
J'ai testé cela et cela fonctionne bien.
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;
}
(Depuis VS2012 ... et au moins jusqu'à VS2017 v15.8.1)
Etant donné qu'il s'agit d'un projet MFC et que CString est une classe MFC, MS fournit une note technique TN059: Utilisation de macros de conversion MBCS/Unicode MFC et de macros de conversion génériques:
A2CW (LPCSTR) -> (LPCWSTR)
A2W (LPCSTR) -> (LPWSTR)
W2CA (LPCWSTR) -> (LPCSTR)
W2A (LPCWSTR) -> (LPSTR)
Utilisation:
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" **
}
-
Notes de bas de page:
(1) Pour que les macros de conversion disposent d'un espace pour stocker la longueur temporaire, il est nécessaire de déclarer une variable locale appelée _convert
qui le fait dans chaque fonction utilisant les macros de conversion. Ceci est fait en appelant la macro USES_CONVERSION
. Dans le code MFC VS2017 (atlconv.h), il se présente comme suit:
#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
Cela fonctionne bien:
//Convert CString to std::string
inline std::string to_string(const CString& cst)
{
return CT2A(cst.GetString());
}
Toutes les autres réponses n'abordaient pas tout à fait ce que je cherchais, à savoir convertir CString
à la volée plutôt que de stocker le résultat dans une variable.
La solution est similaire à celle décrite ci-dessus, mais nous avons besoin d’une étape supplémentaire pour instancier un objet sans nom. Je suis illustrant avec un exemple. Voici ma fonction qui a besoin de std::string
mais j'ai 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;
}
Comment appeler quand vous avez une CString
?
std::string firstName = "First";
CString lastName = _T("Last");
writeLog( firstName + ", " + std::string( CT2A( lastName ) ) );
Notez que la dernière ligne n'est pas un transtypage direct, mais nous créons un objet sans nom std::string
et fournissons la CString
via son constructeur.
Vous pouvez utiliser CT2CA
CString datasetPath;
CT2CA st(datasetPath);
string dataset(st);
Travaille pour moi:
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();
}