ccode_new hat geschrieben: ↑02.08.2022 12:03
Man könnte sogar mit den Rückgabewert überprüfen ob es Unicode oder nicht ist, da hierbei ja mindestens 2 Byte belegt sein müssten. Aber bei Ascii wird das Ganze dann problematisch.
Bei einem negativen Rückgabewert würde man den Fehler sofort beim Übersetzen merken, wenn -1 Byte im Speicher zugewiesen werden soll und nicht erst zur Laufzeit.
Ich verstehe diese Argumentationskette nicht.
Zur ersten Aussage, was meinst du mit "mindestens 2 Byte belegt sein"? Ein valides Unicode-Zeichen (unter 256) besteht immer aus einem Byte und einem 0-Byte. Es unterscheidet sich somit nicht von einer Ascii- oder UTF8- (bis 127) Zeichenkette mit nur einem Zeichen.
Es gibt keine Funktion, die eindeutig ermitteln kann, ob es sich bei einem Speicherbereich um Ascii, UTF8, Unicode oder sonst was handelt. Die einzige Möglichkeit wäre ein
BOM am Anfang des Speicherbereichs zu nutzen oder aber Formate auszuschließen, wenn der Speicher z.B. ungültige Byte-Sequenzen enthält, die in UTF8 oder Unicode keine erlaubten Zeichen darstellen (z.B. die Byte-Werte 192 oder 193 in UTF8).
Bei der zweiten Aussage frage ich mich, in welchem Fall -1 als Wert zurückgegeben werden soll?
- Mit #PB_Ascii wären alle Byte-Werte valide und es wird immer bis 0 gelesen und dann die Länge zurückgegeben oder halt 1 wenn "aus Versehen" ein Unicode-Codierter String gelesen wird, was die Funktion aber nicht von einem 1-Zeichen langen String unterscheiden kann.
- Mit #PB_UTF8 gibt es dasselbe Problem, wobei hier -1 zurückgegeben werden könnte, wenn eine Byte-Sequenzen gefunden wird. Das würde dann aber nur in speziellen Fällen funktionieren.
- Mit #PB_Unicode gibt es sogar das Problem, dass das Zeichenkettenende eines Ascii- oder UFT8-Strings einfach ohne Probleme überlesen werden kann und somit eher zu große Längen zurückgegeben werden.
Hier sind praktisch alle 2-Byte-Werte möglich und es wird solange gelesen bis zwei 0-Byte auftauchen.
Vielleicht auch noch mal zu den Funktionen selbst:
- StringByteLength() wird benutzt, um zu bestimmen, wie viele Byte ein String haben würde, wenn man ihn im angegebenen Format speichern wollen würde.
Also String-to-Memory.
- MemoryStringLength() wird hingegen benutzt, um zu bestimmen, wie viele Zeichen ein String haben würde, wenn man ihn mit dem angegebenen Format aus einem Speicher lesen würde. Also Memory-to-String
Nach deinem Beispiel zu urteilen, wo du PokeS() verwenden möchtest, wäre also nur StringByteLength() die korrekte Wahl!
Ganz nebenbei: Gerade bei der Datenübertragung wäre es fatal die länge einer Zeichenkette anhand der Zeichen selbst zu bestimmen (also nach dem Ende zu suchen). Übertragungsfehler könnten hier schnell zu unvorhergesehenen Lese-Zyklen führen. Daher wird hier normalerweise entweder gleich auf fixe Längen gesetzt oder aber die Länge vorab geschickt, am besten noch mit einer Prüfsumme versehen.