Gibt es ein Problem?
Es gibt mehrere Probleme:
CStringist eine Vorlagenspezialisierung von CStringT . Abhängig vom BaseType , der den Zeichentyp beschreibt, gibt es zwei konkrete Spezialisierungen: CStringA(using char) und CStringW(using wchar_t).
- Während
wchar_tunter Windows allgegenwärtig zum Speichern von UTF-16-codierten Codeeinheiten verwendet wird, ist die Verwendung nicht chareindeutig. Letzteres speichert üblicherweise ANSI-codierte Zeichen, kann aber auch ASCII-, UTF-8- oder sogar Binärdaten speichern.
- Wir kennen die Zeichenkodierung (oder sogar den Zeichentyp) von
CString(die über das _UNICODEPräprozessorsymbol gesteuert wird ) nicht, was die Frage mehrdeutig macht. Wir kennen auch nicht die gewünschte Zeichenkodierung von std::string.
- Die Konvertierung zwischen Unicode und ANSI ist von Natur aus verlustbehaftet: Die ANSI-Codierung kann nur eine Teilmenge des Unicode-Zeichensatzes darstellen.
Um diese Probleme zu beheben, gehe ich davon aus, dass wchar_tUTF-16-codierte Codeeinheiten gespeichert werden und charUTF-8-Oktettsequenzen enthalten. Dies ist die einzig vernünftige Wahl, die Sie treffen können, um sicherzustellen, dass Quell- und Zielzeichenfolgen dieselben Informationen beibehalten, ohne die Lösung auf eine Teilmenge der Quell- oder Zieldomänen zu beschränken.
Die folgenden Implementierungen konvertieren zwischen CStringA/ CStringWund std::wstring/ std::stringMapping von UTF-8 nach UTF-16 und umgekehrt:
#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 };
}
Die verbleibenden zwei Funktionen erstellen C ++ - Zeichenfolgenobjekte aus MFC-Zeichenfolgen, wobei die Codierung unverändert bleibt. Beachten Sie, dass die vorherigen Funktionen zwar nicht mit eingebetteten NUL-Zeichen umgehen können, diese Funktionen jedoch dagegen immun sind.
#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() };
}