2013-03-11 4 views
6

Ich bin auf der Suche nach ein paar Tipps auf dem besten Weg, um eine std::wstring in std::string zu konvertieren - aber a schnelle und schmutzige Konvertierung zur Verwendung als Schlüssel in einem Objekt.C++ - std :: wstring zu std :: string - schnelle und dreckige Konvertierung für den Einsatz als Schlüssel in std :: map

Die Karte ist recht groß, und ist bereits gut in das Projekt integriert bereits, und es gibt nur eine Handvoll von Schlüsseln, die diese Umwandlung erfordern, so denke ich, es verschwenderisch sein wird die Karte in eine ändern, die std::wstring akzeptiert als Schlüssel.

Die Ausgabe der Konvertierung ist nicht wirklich wichtig, aber sie muss konsistent sein, um die korrekten Werte jedes Mal zuverlässig aus der Karte zu ziehen.

Die Anwendung ist eine Windows-Anwendung.

Gibt es ein bekanntes Verfahren, um eine grobe Umwandlung zuverlässig für diesen Zweck durchzuführen? Oder würde der beste Weg über den üblichen, richtigen Umwandlungsprozess sein (wie in dieser SO Frage/Antwort beschrieben: How to convert wstring into string?)?

Edit: Bitte beachten Sie - verlieren Informationen in Ordnung ist solange Dinge konsistent sind. Wenn ich ein paar japanische Schriftzeichen einwerfe und sie konsistent in denselben (möglicherweise Müll) std::string konvertieren, ist das in Ordnung. Dies wird niemals zur Anzeige dienen, sondern nur als Schlüssel zum Herausziehen von Werten aus einer Karte.

Danke!

+0

Ein [Adapter] (http://en.wikipedia.org/wiki/Adapter_pattern)? – krlmlr

+2

Vielleicht sollten Sie die 'std :: wstring 'zu [UTF-8] (http://en.wikipedia.org/wiki/UTF-8) konvertieren und die' std :: string' auf diesen Wert setzen. Sie werden auf diese Weise falsche '\ 0' Bytes vermeiden. –

+0

Warum verwenden Sie überhaupt 'std :: wstring'? [Benutze UTF8 überall.] (Http://utf8everywhere.org/) –

Antwort

7

Wenn Sie nicht an der Semantik des Inhalts interessiert sind, sondern nur an dem Inhalt, um vergleichbar zu sein, werde ich nur die innere wchar [] in ein char [] von doppelter Größe zusammen und verwenden Sie es, um die Zeichenfolge zu initialisieren (durch Angabe von Adresse/Größe im Konstruktor)

std::wstring ws(L"ABCD€FG"); 
std::string s((const char*)&ws[0], sizeof(wchar_t)/sizeof(char)*ws.size()); 

Jetzt s unprintable ist (es kann null Zeichen enthalten), aber immer noch belegbar und vergleichbar.

Yo gehen zurück wie:

std::wstring nws((const wchar_t*)&s[0], sizeof(char)/sizeof(wchar_t)*s.size()); 

vergleichen Jetzt

std::cout << (nws==ws) 

1 gedruckt werden soll.

Beachten Sie jedoch, dass auf diese Weise die Reihenfolge in der Karte (Ergebnis von operator<) ... wegen der Anwesenheit der 0 unscharf ist und keine Text-Semaphys wiedergibt. Die Suche funktioniert jedoch immer noch, da -wie auch immer - es immer noch eine "Bestellung" ist.

+1

Das wird das OP ablenken: Es geht natürlich nicht darum, einen schönen Ausdruck zu haben, sondern zu prüfen, dass während eines Zyklus kein Informationsverlust entsteht. Was auch immer sich in Abhängigkeit von der Gleichheit ändert, spielt sich gleich ab. Ich machte das kürzere und einfachere und benötigte keine zusätzlichen Header. Es liegt an dem OP, den besten "Beautifier" für sein Bedürfnis zu finden (einschließlich Cout durch MessageBox ersetzen oder was auch immer Dialog anzeigt) –

+2

Wenn dies eine unordered_map wäre, wäre ich besorgt über die Null-Bytes in der Zeichenfolge. Wenn die Hashing-Funktion eine Spezialisierung für Strings hat, kann sie die tatsächliche std :: string-Größe berücksichtigen oder nicht und stattdessen beim ersten Null-Byte anhalten. –

7

Sie können std :: wstring in utf-8 konvertieren (mit WideCharToMultiByte oder etwas wie diese lib: http://utfcpp.sourceforge.net/), das heißt, eine null-beendende C-Zeichenfolge, und dann std :: string daraus konstruieren. Diese Umwandlung wird reversibel sein.

+0

+1: ein guter Fund. –

9

Als Variante würde ich für

std::wstring w(L"Some"); 
std::string s(w.begin(), w.end()); 

geht Vielleicht ist die andere Antwort ist schneller (abhängig von der Implementierung String Iteratoren), aber dies ist eine std \ stl Art und Weise wie für mich. Aber ja, das wird einige einzigartige Charaktere verlieren.