Null-terminierte Strings

Übersicht BlitzBasic Codearchiv

Neue Antwort erstellen

PacMani

Betreff: Null-terminierte Strings

BeitragMo, Jan 17, 2011 20:25
Antworten mit Zitat
Benutzer-Profile anzeigen
Zitat:
Worum geht es hier?
Hier findest du zwei kleine Codeschnippsel, mit denen du null-terminierte Strings in Dateien speichern und lesen kannst.
Natürlich wirst du dich jetzt fragen, warum du das gebrauchen könntest. Schließlich kannst du bereits mit Blitz-Bordmitteln Strings speichern und auch wieder lesen.
Bei den Strings hier handelt es sich aber um sogenannte 0-terminierte Strings, die etwas platzsparender abgespeichert werden als die Blitz-Stings, welche in der sogenannten pascalschen Schreibweise gespeichert werden. Null-terminierte Strings sind 3 Bytes kleiner, was bei einer großen Liste von Strings zu einem guten Einsparpotential führen kann.

Zitat:
Wieso sind sie 3 Bytes kleiner?
Um das zu verstehen, erkläre ich dir kurz, wie Blitz Strings in Dateien schreibt.
Ein Blitz-String mit dem Inhalt "Pac-Man" in hexadezimaler Datenansicht sieht so aus:
Code: [AUSKLAPPEN]
            P  a  c  -  M  a  n
07 00 00 00 50 61 63 2D 4D 61 6E

Genauer gesagt schreibt Blitz zuerst einen Int, der die Länge des nachfolgenden Textes enthält. In diesem Fall 7 Zeichen. Ein Int hat die Angewohnheit, 4 Bytes lang zu sein. Das entspricht den 07 00 00 00 am Anfang.
Ein 0-terminierter String enthält keine Auskunft darüber, wie lang ein String ist. Ein 0-String endet dagegen immer mit dem Byte 00:
Code: [AUSKLAPPEN]
P  a  c  -  M  a  n
50 61 63 2D 4D 61 6E 00

Und da als Zusatzinformation nur 1 Byte und nicht ein 4 Byte langer Int angegeben wird, ist ein 0-String also 3 Bytes kleiner!

Zitat:
Na dann her mit den Funktionen... muss ich was beachten?
Die Funktionen sind wie die WriteString() und ReadString()-Methoden von Blitz aufgebaut. Sie unterscheiden sich nur in ihrem Namen:
Code: [AUSKLAPPEN]
;Schreibt einen null-terminierten String ----------------------------------------------------------
Function Write0String(Stream, Value$)
    For i = 1 To Len(Value)
        WriteByte(Stream, Asc(Mid(Value, i, 1)))
    Next
    WriteByte(Stream, 0)
End Function
;Liest einen null-terminierten String -------------------------------------------------------------
Function Read0String$(Stream)
    Local Value$
    Repeat
        i = ReadByte(Stream)
        If i = 0 Then
            Return Value
        Else
            Value = Value + Chr(i)
        End If
    Forever
End Function

Die Funktionen sind selbsterklärend. Die Hilfe zu den verwendeten Asc, Mid und Chr-Befehlen ist völlig ausreichend. Hast du dennoch weitere Fragen, kannst du sie natürlich in diesem Thread posten.

Zitat:
Kann ich die Funktionen mal schnell testen?
Klar, hier ein kleines Beispielprogramm:
Code: [AUSKLAPPEN]
Local File
File = WriteFile("temp")
Write0String(File, "blablabla" + "|")
Write0String(File, "123456789")
WriteInt(File, 0)
Write0String(File, "Commander")
WriteByte(File, 0)
Write0String(File, "  Keen   ")
WriteByte(File, 23)
CloseFile(File)

File = ReadFile("temp")
Print Read0String(File)
Print Read0String(File)
Print ReadInt(File)
Print Read0String(File)
Print ReadByte(File)
Print Read0String(File)
Print ReadByte(File)
CloseFile(File)
DeleteFile("temp")

WaitKey

Es wird eine Datei geöffnet, ein paar Daten in sie hereingeschrieben und wieder ausgelesen. Kannst du genau das lesen, was geschrieben wurde, erfolgt das Speichern und Lesen der Strings erfolgreich!

Zitat:
Jetzt möchte ich aber mehr zum Thema wissen!
Das glaube ich zwar nicht Wink aber hier sind ein paar weiterführende Links:
Eintrag "Zeichenkette" auf Wikipedia
Eintrag "Nullzeichen" auf Wikipedia
  • Zuletzt bearbeitet von PacMani am Sa, Nov 05, 2011 15:43, insgesamt einmal bearbeitet

hazumu-kun

BeitragDi, Jan 18, 2011 17:01
Antworten mit Zitat
Benutzer-Profile anzeigen
Sehr gut dargestellt worums geht.
Aaber deine Funktionen sollten noch auf Stream=0 prüfen.
Warum kann es keine omnipotente Macht geben?
Weil diese omnipotente Macht in der Lage sein müsste, einen so schweren Stein zu schaffen, dass sie ihn nicht heben kann
-> nicht omnipotent

PacMani

BeitragDi, Jan 18, 2011 19:16
Antworten mit Zitat
Benutzer-Profile anzeigen
Daran habe ich auch gedacht. Aber die Blitz-Funktionen machen dass doch auch nicht, wenn ein String nicht vollständig gelesen werden konnte, oder? Also z.B. 07 00 00 00 xx xx EOF verursacht doch einen Fehler?

ToeB

BeitragDi, Jan 18, 2011 19:33
Antworten mit Zitat
Benutzer-Profile anzeigen
Aber das könnte den Fehler übergehen und falls die Datei (aus welchen Gründen auch immer) nicht beschreibbar ist, das dann das Programm intern einen Fehler höchstens geben kann, aber es immer noch weiter läuft.


mfg ToeB
Religiöse Kriege sind Streitigkeiten erwachsener Männer darum, wer den besten imaginären Freund hat.
Race-Project - Das Rennspiel der etwas anderen Art
SimpleUDP3.0 - Neuste Version der Netzwerk-Bibliothek
Vielen Dank an dieser Stelle nochmal an Pummelie, welcher mir einen Teil seines VServers für das Betreiben meines Masterservers zur verfügung stellt!

PacMani

BeitragDi, Jan 18, 2011 19:39
Antworten mit Zitat
Benutzer-Profile anzeigen
Ok. Ich wollte mich so nah wie möglich an die Blitzfunktionen halten. Eine Fehlerabsicherung dem User anvertrauen (an sich sollten derartige Strings schließlich nicht auftreten - dann wurden Daten in der falschen Reihenfolge gelesen und durch Fehlerabsicherung meinerseits wird man nicht / nie darauf aufmerksam).

Ich würde dass dann so lösen, und bei solchen Vorfällen im DebugLog eine Warnung ausgeben:
Code: [AUSKLAPPEN]
;Liest einen null-terminierten String (fehlerabgesichert) -------------------------------------------
Function Read0String_S$(Stream)
    Local Value$
    Repeat
        i = ReadByte(Stream)
        If i = 0 Then
            Return Value
        Else
            Value = Value + Chr(i)
        End If
    Until Eof(Stream) = 0
    DebugLog "Warning: Unfinished 0-terminated string read with content '" + Value + "'."
    Return Value
End Function
  • Zuletzt bearbeitet von PacMani am Mi, Jan 19, 2011 14:55, insgesamt einmal bearbeitet

aMul

Sieger des Minimalist Compo 01/13

BeitragMi, Jan 19, 2011 14:26
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich glaube du solltest lieber Until schreiben, und nicht While. Wink (Oder gleich eine While-Wend-Schleife, die denke ich hier mehr Sinn macht.)
Code: [AUSKLAPPEN]
;Liest einen null-terminierten String (fehlerabgesichert) -------------------------------------------
Function Read0String_S$(Stream)
    Local Value$
    While Eof(Stream) = 0
        i = ReadByte(Stream)
        If i = 0 Then
            Return Value
        Else
            Value = Value + Chr(i)
        End If
    Wend
    DebugLog "Warning: Unfinished 0-terminated string read with content '" + Value + "'."
    Return Value
End Function
Panic Pong - ultimate action mashup of Pong and Breakout <= aktives Spiele-Projekt, Downloads mit vielen bunten Farben!
advASCIIdraw - the advanced ASCII art program <= aktives nicht-Spiele-Projekt, must-have für ASCII/roguelike/dungeon-crawler fans!
Alter BB-Kram: ThroughTheAsteroidBelt - mit Quelltext! | RGB-Palette in 32²-Textur / Farbige Beleuchtung mit Dot3 | Stereoskopie in Blitz3D | Teleport-Animation Screensaver

PacMani

BeitragMi, Jan 19, 2011 14:55
Antworten mit Zitat
Benutzer-Profile anzeigen
Oh ok, sorry, hatte gestern schnell im Kopf gecoded und es nicht weiter getestet.

Neue Antwort erstellen


Übersicht BlitzBasic Codearchiv

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group