Hallo,
wenn ich in Visual Studio ein neues Projekt erstelle, ist Unicode
voreingestellt. Prüfe ich z.B. ein Laufwerk mit folgendem Code...
1
if (GetDriveType("m:\\")!=3) {}
...erhalte ich folgenden Fehler:
error C2664: 'GetDriveTypeW': Konvertierung des Parameters 1 von 'const
char [4]' in 'LPCWSTR' nicht möglich
Stelle ich auf Multibyte um, wird ordentlich kompiliert und das Programm
läuft. Ich könnte jetzt bei jedem Projekt Multibyte einstellen, aber ich
frage mich, ob das so sinnvoll ist oder ob man besser mit Unicode
programmiert? Aber was muss man - mal auf mein Beispiel bezogen - anders
machen, um mit Unicode fehlerfrei kompilieren zu können?
Gruß,
Tom
Hallo,
danke, nach dem includen von tchar.h kompiliert Visual Studio deinen
Code ohne Fehler.
Aber ist das nicht ziemlich umständlich, jedes mal diese Klammern und
das Text-Makro zu setzen?
Gibt es in Visual C++ 2008 Express Edition nicht die Möglichkeit, dass
alles was in Klammern gesetzt ist, automatisch als Unicode aufgefasst
wird? Ich meine, wenn ich in den Projektvoreinstellungen den Zeichensatz
schon auf Unicode stelle, warum muss ich dann bei Text-Zuweisungen jedes
mal noch explizit mit _T() umwandeln?
Wenn ich das richtig verstehe, ist der Unterschied zwischen den beiden
Zeichensätzen der, dass bei Unicode immer 4 Byte pro Zeichen verwendet
werden, wohingegen bei Multibyte eine variable Anzahl von Bytes(im
besten Fall nur 2 Bytes) nötig sind. Mal angenommen ich bin Faul und
programmiere mit Zeichensatz Multibyte...hat das - abgesehen von den
Problemen, wenn ich bestimmte Positionen im gespeicherten Text
anspringen möchte - später irgendwelche Nachteile(z.B. das mein Programm
in Windows 8 unter Umständen nicht mehr läuft)?
Vielen Dank schonmal....
Tom
Tom schrieb:> Gibt es in Visual C++ 2008 Express Edition nicht die Möglichkeit, dass> alles was in Klammern gesetzt ist, automatisch als Unicode aufgefasst> wird? Ich meine, wenn ich in den Projektvoreinstellungen den Zeichensatz> schon auf Unicode stelle, warum muss ich dann bei Text-Zuweisungen jedes> mal noch explizit mit _T() umwandeln?
Stringkonstanten sind Stringkonstanten, und die sind eben vom Typ char*.
Und char ist 8 Bit groß, unabhängig davon, ob mit Unicode- oder
"Multibyte" gearbeitet wird.
Mit _T() kannst Du ohne großen Aufwand 16-Bit-Stringkonstanten anlegen.
Die Alternative wäre eine Konvertierung mit Hilfe der Win32-API-Funktion
MultiByteToWideChar.
Tom schrieb:> Wenn ich das richtig verstehe, ist der Unterschied zwischen den beiden> Zeichensätzen der, dass bei Unicode immer 4 Byte pro Zeichen verwendet> werden, wohingegen bei Multibyte eine variable Anzahl von Bytes(im> besten Fall nur 2 Bytes) nötig sind.
Teile die Zahlen durch 2, dann stimmts.
Nur mal so am Rande gefragt: Warum willst Du Unicode verwenden?
Schreibst Du Anwendungen, die nicht mit dem in CP1252 enthaltenen
Zeichensatz auskommen?
Rufus t. Firefly schrieb:> Mit _T() kannst Du ohne großen Aufwand 16-Bit-Stringkonstanten anlegen.
Mit _T kannst Du aber auch ohne großen Aufwand 8-Bit-Stringkonstanten
anlegen, je nach Art der Kompilierung. Will man wirklich nur Unicode,
reicht ein einfaches L. Dann würde ich allerdings auch GetDriveTypeW
anstelle von GetDriveType verwenden:
1
if (GetDriveTypeW(L"m:\\")!=3) {}
> Nur mal so am Rande gefragt: Warum willst Du Unicode verwenden?> Schreibst Du Anwendungen, die nicht mit dem in CP1252 enthaltenen> Zeichensatz auskommen?
Mal so am Rande gefragt: Schreibst Du tatsächlich noch Anwendungen, die
nicht Unicode verwenden? :-)
Im Ernst: Unicode vereinfacht, zumindest unter Windows, einiges. In COM
ist z.B. ohnehin alles Unicode. Und da unter der Haut auch alles Unicode
ist, bringt Dir das sogar noch einen Geschwindigkeitsvorteil, da das
Konvertieren von und nach Unicode vor und nach den Funktionsaufrufen
entfällt.
René König schrieb:> al so am Rande gefragt: Schreibst Du tatsächlich noch Anwendungen, die> nicht Unicode verwenden? :-)> Im Ernst: Unicode vereinfacht, zumindest unter Windows, einiges. In COM> ist z.B. ohnehin alles Unicode. Und da unter der Haut auch alles Unicode> ist, bringt Dir das sogar noch einen Geschwindigkeitsvorteil, da das> Konvertieren von und nach Unicode vor und nach den Funktionsaufrufen> entfällt.
ich muss auch sagen dasa erste was ich bei einem Projekt machen ist
unicode abzuschalten, weil ich es noch nie gebraucht habe. Vermutlich
würde meine Programm auch nicht laufen weil ich gerne mal ein char*
verwende.
Peter schrieb:> ich muss auch sagen dasa erste was ich bei einem Projekt machen ist> unicode abzuschalten, weil ich es noch nie gebraucht habe. Vermutlich
Gebraucht habe ich das schon: Unter Windows Mobile geht es nämlich gar
nicht anders.
> würde meine Programm auch nicht laufen weil ich gerne mal ein char*> verwende.
Und ich verwende TCHAR*, das funktioniert mit und ohne Unicode. Man
gewöhnt sich daran.
Rufus t. Firefly schrieb:> Tom schrieb:>> Wenn ich das richtig verstehe, ist der Unterschied zwischen den beiden>> Zeichensätzen der, dass bei Unicode immer 4 Byte pro Zeichen verwendet>> werden, wohingegen bei Multibyte eine variable Anzahl von Bytes(im>> besten Fall nur 2 Bytes) nötig sind.>> Teile die Zahlen durch 2, dann stimmts.
Dann ist es aber kein Unicode, denn das paßt nicht in 2 Bytes.
> Nur mal so am Rande gefragt: Warum willst Du Unicode verwenden?
Ich finde es irgendwie albern, heute noch mit dem Zeichensatzchaos
rumzuhantieren. Gerade um das nicht zu müssen, wurde Unicode geschaffen.
Rolf Magnus schrieb:> Gerade um das nicht zu müssen, wurde Unicode geschaffen.
aber meine µC verstehe keine Unicode also muss ich eh zurückwandeln.
Auch hatte ich noch keine Probleme mit irgendwelchen Zeichensätzen. Wenn
der User ein ü eingibt und ich bei der ausgabe ihm das gleiche zeichen
zurück liefere ist mir doch der zeichensatz egal.
Ich musste bis jetzt noch nicht für Klingonen Software erstellen.
Rufus t. Firefly schrieb:> Rolf Magnus schrieb:>> Dann ist es aber kein Unicode, denn das paßt nicht in 2 Bytes.>> Doch, tut es. MS implementiert 16-Bit-Unicode.
Meinst du USC-2? Das ist nicht 16-Bit-Unicode, sondern entspricht einem
16-Bit-Subset von Unicode. Unicode enthält fast 110.000 Zeichen.
Die Grundlagen für die Unicodeunterstützung der ernstgemeinten
Windows-Versionen stammen aus den frühen 90er Jahren, also aus der Zeit
vor Unicode 2.0 (das von '96 ist).
Wenn man sich die Dokumentation* der von mir erwähnten Funktion
MultiByteToWideChar ansieht, dann wird klar, was MS unter Unicode
versteht:
> MultiByteToWideChar Function>> Maps a character string to a UTF-16 (wide character)> string. The character string is not necessarily from> a multibyte character set.
*) http://msdn.microsoft.com/en-us/library/dd319072%28VS.85%29.aspx
Rufus t. Firefly schrieb:>> Maps a character string to a UTF-16 (wide character)
Und damit kann ein Character auch schon mal 4 Bytes umfassen, wenn ich
das richtig verstehe: "In the UTF-16 encoding form, code points in the
range U+0000..U+FFFF are represented as a single 16-bit code unit; code
points in the supplementary planes, in the range U+10000..U+10FFFF, are
represented as pairs of 16-bit code units."
Quelle: http://www.unicode.org/versions/Unicode5.2.0/ch02.pdf
Seite 22, unter UTF16
Und ganz genau so beschreibt es auch Microsoft, wenn ich Deinem Link
folge: "The use of 16 bits allows the direct encoding of 65,536
characters. In fact, the universe of symbols used to transcribe human
languages is even larger than that, and UTF-16 code points in the range
U+D800 through U+DFFF are used to form surrogate pairs, which constitute
32-bit encodings of supplementary characters."
Quelle:
http://msdn.microsoft.com/en-us/library/dd374081%28v=VS.85%29.aspx
Rufus t. Firefly schrieb:> Die Grundlagen für die Unicodeunterstützung der ernstgemeinten> Windows-Versionen stammen aus den frühen 90er Jahren, also aus der Zeit> vor Unicode 2.0 (das von '96 ist).
Ist also ähnlich wie bei ISO-C: Microsoft lebt weit in der
Vergangenheit.
René König schrieb:> Rufus t. Firefly schrieb:>>> Maps a character string to a UTF-16 (wide character)>> Und damit kann ein Character auch schon mal 4 Bytes umfassen, wenn ich> das richtig verstehe: "In the UTF-16 encoding form, code points in the> range U+0000..U+FFFF are represented as a single 16-bit code unit; code> points in the supplementary planes, in the range U+10000..U+10FFFF, are> represented as pairs of 16-bit code units."
Ja, UTF-16 funktioniert ähnlich wie UTF-8, nur eben auf 16-Bit-Basis.
Wobei ich mir unter "Wide Character" immer die mit fester Größer > 8 Bit
vorgestellt habe und unter "Multibyte Character" die, die je nach
Zeichen unterschiedlich groß sein können.
Das was MS als UTF-16 bezeichnet, ist nix anderes als UCS-2, also ein
2-Byte Character Set. Genau daselbe, was man bekommt, wenn man im
Notepad irgendwas als Unicode abspeichert. Im Hexeditor sieht man dann
immer schön zwei Bytes pro Zeichen, egal ob es ein pures ASCII-Zeichen
ist, oder irgendwas aus Fernost.
UTF-8 dagegen besteht aus 1 bis 4 Byte pro Zeichen - ist also variable.
Jens G. schrieb:> Das was MS als UTF-16 bezeichnet, ist nix anderes als UCS-2, also ein> 2-Byte Character Set.
Das ist leider falsch:
Die MS Implementierung der API ist UTF-16LE, als eine mögliche Kodierung
der Unicode-Codepoints (Codepoints sind die Hex-Werte die jedes Zeichen
in Unicode eindeutig beschreiben).
Damit sind Unicode-Zeichen mit Codepoints U0x0 - U0xFFFF mit einem
16bit-Wert darstellbar, während die Unicode-Zeichen mit Codepoints
>U0xFFFF als Surrogate-Pairs (d.h. mit zwei 16bit-Werten) dargestellt
werden.
Historisch kanne Windows NT bis NT 4.0 keine Surrogate-Pairs (waren die
Unicode-Zeichen mit Codepoints >U0xFFFF damals überhaupt schon
erfunden?).
Mit Windows 2000 und ff. kam die Unterstützung für Surrogate-Pairs dazu.
Loeti schrieb:> (waren die> Unicode-Zeichen mit Codepoints >U0xFFFF damals überhaupt schon> erfunden?).
Nein, die kamen erst 1996 mit Unicode 2.0, so wie ich das verstanden
habe und mich noch vage erinnere.
>Historisch kanne Windows NT bis NT 4.0 keine Surrogate-Pairs (waren die>Unicode-Zeichen mit Codepoints >U0xFFFF damals überhaupt schon>erfunden?).
Nun - dann war wohl mein diesbezügliches Wissen etwas altbacken ...
Aber ...
>Damit sind Unicode-Zeichen mit Codepoints U0x0 - U0xFFFF mit einem>16bit-Wert darstellbar, während die Unicode-Zeichen mit Codepoints>>U0xFFFF als Surrogate-Pairs (d.h. mit zwei 16bit-Werten) dargestellt>werden.
kann trotzdem nicht stimmen, denn mindestens irgendein Wert zw. U0x0 -
U0xFFFF muß ja als Surrogate definiert sein. Es kann also nicht U0x0 -
U0xFFFF lückenlos als Codepointbereich für normale Zeichen herhalten.
Jens G. schrieb:> kann trotzdem nicht stimmen, denn mindestens irgendein Wert zw. U0x0 -> U0xFFFF muß ja als Surrogate definiert sein. Es kann also nicht U0x0 -> U0xFFFF lückenlos als Codepointbereich für normale Zeichen herhalten.
Da hast Du natürlich recht, von
http://unicode.org/faq/utf_bom.html#utf16-2
kopiert:
Q: What are surrogates?
A: Surrogates are code points from two special ranges of Unicode values,
reserved for use as the leading, and trailing values of paired code
units in UTF-16. Leading, also called high, surrogates are from D80016
to DBFF16, and trailing, or low, surrogates are from DC0016 to DFFF16.
They are called surrogates, since they do not represent characters
directly, but only as a pair.
Somit sind (obwohl es ja gaaanz theoretisch möglich wäre ;-)
diese Codepoints als Surrogate leading und trailing UTF16-Werte
reserviert
und können für sich allein kein Zeichen darstellen.
loeti schrieb:> Somit sind (obwohl es ja gaaanz theoretisch möglich wäre ;-)
Das ist natürlich Käse, da ja gerade ein Vorteil der Surrogate-Pairs
ist daß sie beim Suchen des Strings vorwärts und rückwärts eindeutig
und schnell gefunden werden.
Bei den Multibyte Zeichensätzen und bei UTF-8 muß ja um rückwärts
zeichen-
weise zu laufen, gleichzeitig vom Anfang der Zeichenkette nach
Mehrbyte-Zeichen gesucht werden.
> Bei den Multibyte Zeichensätzen und bei UTF-8 muß ja um rückwärts> zeichen-> weise zu laufen, gleichzeitig vom Anfang der Zeichenkette nach> Mehrbyte-Zeichen gesucht werden.
Bi irgendwelchen Multibyte-Zeichensätzen auf der Welt mag das zwar der
Fall sein, bei UTF-8 aber genügt die Rückwärtssuche allein und ohne
Verrenkungen.
Das erste Byte einer UTF-8-Mehrbyte-Zeichenfolge beginnt eindeutig mit
11xxxxxx, die anderen mit 10xxxxxx. Außerdem lässt sich am so
gekennzeichneten ersten Byte ablesen, wie viel Bytes die Folge insgesamt
hat. Also besteht keinerlei Notwendigkeit, vom Anfang der Zeichenkette
nach Mehrbyte-Folgen zu suchen.