Frage

CString ist ganz praktisch, während std::string mehr kompatibel mit STL-Container ist. Ich verwende hash_map. Allerdings hash_map nicht CString als Schlüssel unterstützen, so möchte ich CString in std::string konvertieren.

Schreiben eine CString Hash-Funktion scheint eine Menge Zeit in Anspruch nehmen.

CString -----> std::string

Wie kann ich das tun?

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

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

Habe ich Recht?


EDIT:

Hier sind weitere Fragen:

Wie kann ich konvertieren wstring, CString miteinander?

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

Gibt es jede Problem?

Wie kann ich konvertieren std::wstring, std::string miteinander?

War es hilfreich?

Lösung

Nach MS-Office-:

CString zu std::string:

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

ABER: std::string kann aus einem LPCTSTR nicht immer konstruieren. das heißt der Code für UNICODE nicht baut.

Als std::string nur aus LPSTR / LPCSTR konstruieren kann, ein Programmierer, die 7.x VC ++ verwendet oder besser kann Konvertierungsklassen nutzen wie CT2CA als Vermittler auf.

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

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

CStringT kann sowohl von Zeichen oder Weitzeichenketten aufzubauen. das heißt, es kann von char* zu konvertieren (das heißt LPSTR) oder von wchar_t* (LPWSTR).

Mit anderen Worten: char-Spezialisierung (von CStringT), dh CStringA, wchar_t-specilization CStringW und TCHAR-Spezialisierung CString kann entweder char oder Breitzeichen konstruiert werden, null beendet (Null-Terminierung ist sehr wichtig, hier) string Quellen.
Althoug IInspectable ändert die "Null-Terminierung" -Teil in den Kommentare :

  

NUL-Beendigung ist nicht erforderlich .
  CStringT hat Umwandlung Konstrukteuren, die eine explizite Länge Argument. Das bedeutet auch, dass Sie CStringT Objekte aus std::string Objekten mit eingebetteten NUL Zeichen konstruieren können.

Andere Tipps

Lösen Sie, dass durch std::basic_string<TCHAR> statt std::string verwenden und es sollte unabhängig von Ihrem Charakter Einstellung funktionieren.

Es ist leistungsfähigere CString zu konvertieren die Konvertierung std::string mit denen die Länge angegeben ist.

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

In enger Schleife dies macht eine deutliche Leistungssteigerung.

Wenn Sie etwas mehr C ++ wollen - wie, das ist, was ich benutze. Obwohl es auf Boost-abhängig ist, ist das nur für Ausnahmen. Sie können diese leicht entfernen lassen nur auf der STL und der WideCharToMultiByte() Win32-API-Aufruf abhängig zu sein.

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

Dies funktioniert:

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

von diesem Posten (Danke Mark Ransom )

Konvertieren CString string (VC6)

Ich habe das getestet und es funktioniert gut.

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

Funktioniert bei mir:

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

Alle anderen Antworten nicht ganz Adresse, was ich für die suchte CString on the fly zu konvertieren war im Gegensatz das Ergebnis in einer Variablen zu speichern.

Die Lösung ist ähnlich wie oben, aber wir brauchen einen weiteren Schritt ein namenlos Objekt zu instanziiert. Ich illustriert mit einem Beispiel. Hier ist meine Funktion, die std::string braucht aber ich habe 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;
}

Wie es nennen, wenn Sie eine CString haben?

std::string firstName = "First";
CString lastName = _T("Last");

writeLog( firstName + ", " + std::string( CT2A( lastName ) ) );     

Beachten Sie, dass die letzte Zeile nicht eine direkte Typumwandlung ist, aber wir sind ein namenlos std::string Objekt und liefert die CString über den Konstruktor zu schaffen.

  

Gibt es jede Problem?

Es gibt mehrere Probleme:

  • CString ist eine Vorlage Spezialisierung der CStringT . Je nach der Basetype beschreibt den Zeichentyp gibt es zwei konkrete Spezialisierungen. CStringA (mit char) und CStringW (mit wchar_t)
  • Während wchar_t auf Windows ubiquitär speichern UTF-16 codierten Codeeinheiten verwendet, char Verwendung ist nicht eindeutig. Letztere häufig speichert ANSI-Zeichen codiert, kann aber auch speichern ASCII, UTF-8, oder auch binäre Daten.
  • Wir wissen nicht, die Zeichenkodierung (oder sogar Art Zeichen) von CString (die durch das _UNICODE Präprozessorsymbol gesteuert wird), so dass die Frage nicht eindeutig. Wir wissen nicht, auch die gewünschte Zeichencodierung von std::string.
  • Konvertierung zwischen Unicode und ANSI ist von Natur aus mit Verlust behaftete. ANSI-Codierung nur eine Teilmenge des Unicode-Zeichensatzes darstellen kann

Um diese Probleme zu adressieren, ich werde diesen wchar_t anzunehmen, UTF-16 kodierte Codeeinheiten speichern und char wird UTF-8-Oktett Sequenzen halten. Das ist die einzige vernünftige Wahl Sie sicherstellen, machen können, dass Quell- und Zielzeichenketten die gleichen Informationen behalten, ohne die Lösung zu einer Teilmenge der Quell- oder Zieldomänen zu begrenzen.

Die folgenden Umsetzungen wandeln zwischen CStringA / CStringW und std::wstring / std::string Abbildung von UTF-8 in 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 konstruieren C ++ String-Objekte aus MFC-Strings, so dass die Codierung unverändert. Beachten Sie, dass die bisherigen Funktionen können nicht mit eingebetteten NUL-Zeichen fertig zu werden, diese Funktionen zu, dass 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() };
}

Sie können mit CT2CA

CString datasetPath;
CT2CA st(datasetPath);
string dataset(st);

Wenn Sie schauen einfach zwischen anderen Saiten-Typen konvertieren, vielleicht das _bstr_t Klasse wäre besser geeignet sein? Es unterstützt converstion zwischen char, wchar_t und BSTR.

Ein interessanter Ansatz ist CString zu werfen in einem CStringA Konstruktor string. Im Gegensatz zu std::string s((LPCTSTR)cs); wird dies funktionieren, selbst wenn _UNICODE definiert ist. Wenn dies jedoch der Fall, so wird diese Umwandlung von Unicode in ANSI durchzuführen, so ist es für höhere Unicode-Werte über den ASCII-Zeichensatz unsicher. Eine solche Umwandlung ist auf die _CSTRING_DISABLE_NARROW_WIDE_CONVERSION Präprozessordefinition Thema. https://msdn.microsoft.com/en-us/library/5bzxfsea. aspx

        CString s1("SomeString");
        string s2((CStringA)s1);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top