von char (1 Byte) zu UTF8 (2 Byte)
-
Hallo.
Hab schon einiges probiert, aber komme zu keiner Lösung die komplett funktioniert.
Mein Problem ist, dass ich ein char Zeichen als UTF8 Zeichen brauche.
Also ich will Beispielsweise, dasschar cMultiByte = 'ä' //cMultiByte ist also 0xE4 und größer 127
zu
char cUnicode[2] = {'Ã', '¤') //Also den Unicode Wert von ä
wird
...also ein 1 byte Zeichen zu 2Byte Unicode konvertieren, sobald es ein ANSI Zeichen (größer 127) wird.
Könnt ihr mir da ein paar Ansätez geben?Ich programmieren in Visual Studio 2005 Pro und die Zeichensatzeinstellungen der Projekteigenschaften sind auf Multi-Byte-Zeichensatz eingestellt.
Freue mich auf eure Hilfe.
-
Schreib's dir selbst. Anhand des entsprechenden Wikipedia-Artikels ist das wirklich nicht schwer. Du brauchst nur die Umwandlung UTF-32 -> UTF-8 zu implementieren, da die ersten 256 Unicodezeichen glaub ich ISO-8859-1 sind.
-
Was meinst du mit UTF-32->UTF-8 implementieren?
Ich hatte es mir ja selber geschrieben, aber beim € Zeichen haut es beispielsweise wieder nicht hin. Das brauch 3 Byte in UTF-8, obwohl es das erste Zeichen eines ANSI Zeichen ist, also in 1 Byte passt.
-
utf8 zeichen haben eine variable größe. die zeichen sind zwischen 1 und 4 byte groß. die ansi zeichen haben in utf8 auch alle 1 byte und den gleichen wert. du kannst dir als beispiel mal die implementierung der wxMBConv klassen aus der wxWidgets bibliothek ansehen.
-
Du willst auch keine Encodings außer ISO-8859 (latin1) nach UTF-8 umwandeln. Das macht keinen Spaß. Code her
-
Also ich hatte es bis jetzt so
//der zu wandelnde string std::string sString = "älala"; unsigned char ucUnicodeChar; const char *cOriginString = sString.c_str(); //der konvertierte string std::string sFinalString; //laenge der Zeichenkette uiStringLength = (unsigned int)sString.size(); //fuer jedes Zeichen in der Zeichenkette for( unsigned int i = 0; i < uiStringLength; i++ ) { ucUnicodeChar = cOriginString[i]; //bei Byte kleiner 127 (signed char) in unicode kodieren if( ucUnicodeChar > 0x7F ) { //wenn Euro zeichen if( ucUnicodeChar == 0x80 ) { char cUnicodeByte1; cUnicodeByte1 &= 0xE2; char cUnicodeByte2; cUnicodeByte2 &= 0x82; char cUnicodeByte3; cUnicodeByte3 &= 0xAC; sFinalString.operator += ( cUnicodeByte1 ); sFinalString.operator += ( cUnicodeByte2 ); sFinalString.operator += ( cUnicodeByte3 ); } //wenn anderes Zeichen else { char cUnicodeByte1 = ucUnicodeChar; char cUnicodeByte2 = ucUnicodeChar; //das erste Byte fuer Zeichen in unicode cUnicodeByte1 >>= 6; //6 Bits nach rechts shiften (1111 11xx) cUnicodeByte1 &= 0x03; //ersten 6 Bits auf 0 setzen (0000 00xx) cUnicodeByte1 |= 0xC0; //ersten 2 Bits auf 1 setzen (1100 00xx) //das zweite Byte fuer Zeichen in unicode cUnicodeByte2 &= 0x3F; //obersten 2 Bits auf 0 (00xx xxxx) cUnicodeByte2 |= 0x80; //obersten 2 Bits auf 10 (10xx xxxx) //unicode Zeichenkette anhaengen sFinalString.operator += ( cUnicodeByte1 ); sFinalString.operator += ( cUnicodeByte2 ); } } else sFinalString.operator += ( cOriginString[i] ); }
-
also multi-byte-zeichensatz klingt für mich schon nach utf8. find mal heraus, in welchem charset deine datei gespeichert ist. du wirst nämlich ein problem bekommen, wenn deine string konstanten schon utf8 sind. die wirst du dann nicht ein zweites mal nach utf8 konvertieren können.
-
Also das hilft mir alles nicht sehr weiter. Man kann übrignes zwischen MultiByte udn Unicode wählen... also kann MultiByte nicht wirklich unicode sein.
vielleicht mal als hintergund... ich lese über WMI daten aus und konvertiere sei von einem VARIANT in einen std::string. diesen string will ich dann mit tinyXML in eine xml datei speichern. tinyxml wandelt aber die zeichen nicht automatisch in UTF8 um, wie ich sie aber für diese xml datei brauche. da ich die xml datei in eine access datenbank importieren will, seh ich eben oft das er sagt "ungültiges xml" zeichen.
und tinyXML will eben (const std::string &_value) haben und dieser referenz auf einen string muss ja dann wohl in UTF8 sein. also ich weiß nicht so ganz weiter... brauch aber jetzt ne lösungHILFE HILFE
-
du musst halt wissen, was bei der konvertierung von VARIANT zu std::string passiert und in welchem charset der string dann ist. du könntest ihn in eine datei ausgeben und dann mit einem hexeditor ansehen. möglich natürlich mit zeichen, die nicht teil von ascii sind. oder du liest die doku. es ist aber allgemein nicht sehr einfach sicher, verschiedene apis zu kombinieren. hsat schon mal an das msxml zeug gedacht? vielleicht klappt das damit besser.
-
Ja da weiß ich was passiert.
Also wichtig ist das ja nur wenn die eingelesenen WMI Daten in das VARINAT vom Typ BSTR sind. BSTR ist ja nun letztendlich ein wchar_t, also eigentlich für 16 Bit unicode.
Deswegen mache ich dann nur noch folgendes//vVariant ist jetzt genau das Variant, welches von der WIN API //funktion zum auslesen der WMI Daten kommt und einen BSTR //enthält. Also unverändert nach dem die Systemfunktion //reingeschrieben hat. std::string sVarString; _bstr_t bstr_t( vVariant.bstrVal ); sVarString.operator = (bstr_t); SysFreeString( bstr_t );
Nun muss ich wohl mal untersuchen, wass beim zuweisen des _bstr_t an den std::string passiert.
-
Kann es sein das meine Fragestellung doch etwas falsch war? Eigentlich habe ich doch unicode und will es in UTF8 kodieren oder?
-
Nicht, dass ich Ahnung hätte, aber vielleicht helfen dir folgende Links:
-
Danke. Deine links (vor allem der erste) haben mir auf jedenfall weiter geholfen. ich habe nun für meine xml datei erstmal ISO-8859-1 genommen, da ich keine zeit mehr habe jetzt alles korrekterweise auf std::wstring, etc. umzubauen.