Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Datei mit "#0" schreiben? (https://www.delphipraxis.net/89594-datei-mit-0-schreiben.html)

xZise 2. Apr 2007 23:06


Datei mit "#0" schreiben?
 
Ich wollte ein bisschen mit Dateien experimentieren, und hatte die Idee, dass ja TStringList.LoadFromFile() bis zum #0 liest. Ich wollte aber weiter Informationen hinterlegen, und dachte mir:
Code:
Normaler

Inhalt
#0
Extra Inhalt#0
... Wie ist das möglich?
Ich habe da an TFileStream gedacht, aber ich kenne mich da nicht aus, und habe auch danach gesucht weis aber nicht, wie ich die Suche einschränken könnte...

Also das soll der Effekt sein:
Ich möchte eine Datei einlesen, bis zum ersten #0 lesen, dass dann als string bearbeiten und dann bis zum 2. #0 lesen (wenns eins gibt) und das als weiteren String bearbeiten...

3_of_8 2. Apr 2007 23:17

Re: Datei mit "#0" schreiben?
 
Soweit ich weiß sind Delphi-Strings nullterminierte Char-Arrays, das heißt, an der Stelle, wo ein #0 ist, ist für Delphi der String zu Ende. Du wirst wohl nicht umhinkommen, das ganze "per Hand" zu laden, also mit einem Filestream und immer schön schauen, ob grad ein #0 da ist.

Ein Filestream lässt sich recht leicht bedienen:

Delphi-Quellcode:
var buf: Char;
    str: String;
    fs: TFileStream;
begin
  fs:=TFileStream.Create('Dateiname', fmOpenRead, fmShareDenyWrite);
  try
    while fs.Position<fs.Size do
    begin
      fs.Read(buf, 1);
      if buf=#0 then
        //...
      else
        str:=str+buf;
    end;
  finally
    fs.Free;
  end;
end;

xZise 2. Apr 2007 23:27

Re: Datei mit "#0" schreiben?
 
Ah danke ;) Jetzt mal ne Frage, die nicht so richtig dazu passt, aber mir dennoch wichtig ist:
"Muss" ich denn den 2. Teil (nach #0) auch irgendwie mit "#0" o.s.ä. beenden, oder tuts das "fs.size"?

himitsu 2. Apr 2007 23:41

Re: Datei mit "#0" schreiben?
 
Zitat:

Zitat von 3_of_8
Soweit ich weiß sind Delphi-Strings nullterminierte Char-Arrays, das heißt, an der Stelle, wo ein #0 ist, ist für Delphi der String zu Ende.

nein, ist er nicht.

Delphi-Quellcode:
S := '123'#0'456';
If S = '' Then ; << mach hier mal einen Breakpoint und schau was in S drin ist ;)
DelphiStrings haben eine Längenangabe und da nur diese ausgewertet wird, is eine #0 im String völlig irrelevant.

Bei Umwandlungen in PChar, wird die Längenangabe nicht beachtet, aber dafür dann die #0.


@Zise: es wäre dennoch einfacher nicht die #0 zu verwenden ... #1..#7, #9, #11, #12 oder #14..#31 bieten sich doch auch an?
> Steuerzeichen (#0..#31) - CR, LF, Tab (#8 #10 #13)

Dann kannst du alles mögliche zum Einlesen verwenden und auch die bekannten Funktionen zum String-Zerlegen (ziehe CodeLib) könnte z.B. mit dem Zeichen #1 wunderschön genutzt werden.

xZise 2. Apr 2007 23:49

Re: Datei mit "#0" schreiben?
 
Das wichtige ist eben, dass mit dem Aufruf TStringList.LoadFromFile er am Stoper abbricht ... Und ich habe schon selber erfahren müssen, dass es mit #0 geht...

PS: Das einlesen klappt super ^^ Danke 3 of 8 ;)

3_of_8 3. Apr 2007 00:05

Re: Datei mit "#0" schreiben?
 
Zitat:

Zitat von himitsu
nein, ist er nicht.

Delphi-Quellcode:
var str: String;
begin
  str:='wuppdi';
  showmessage(inttostr(PByte(Cardinal(@str[6])+1)^));
end;
Oder, als Assembler-Version:
Delphi-Quellcode:
function blubb(s: String): Byte;
asm
  mov al, byte ptr eax+6
end;

procedure TForm1.FormCreate(Sender: TObject);
var str: String;
begin
  str:='wuppdi';
  showmessage(inttostr(blubb(str)));
end;
Wie du siehst, kommt immer 0 raus. Warum? Damit Strings sich schnell und leicht in PChars konvertieren lassen und man nicht jedesmal Speicher neu reservieren muss, wenn man mal schnell nen String an die WinAPI schickt.


Allerdings ist der String 'wup'#0'di' für Delphi tatsächlich 'wup'#0'di' und nicht 'wup'. Da habe ich mich getäuscht. Sobald man jedoch versucht, in per showmessage o.ä. auszugeben, bleibt nur noch ein 'wup' übrig.

Hansa 3. Apr 2007 00:11

Re: Datei mit "#0" schreiben?
 
Stichwort : TInifile. Würde ich mir mal ansehen. Mit #0 oder WinApi am Betriebssystem rumzufummeln würde ich mir gründlich überlegen.

himitsu 3. Apr 2007 00:29

Re: Datei mit "#0" schreiben?
 
@3_of_8: das mit dem abschließendem #0 in String hab ich nie bezweifelt ... nutze es ja selber für 'ne schnelle String-PChar-Konvertierung, ohne PChar(S) aus.

Aber warum es mit ShowMessage nicht geht ist recht einfach erklärt ... dieses übergibt ja intern zum Darstellen den String an eine WinPAI-Funktion auf, welche ja die Strings als PChar entgegen nimmt. :zwinker:



@xZise: TStringList.LoadFromFile ließt die gesamte Datei ein, nur ruft es danach TStringList.SetTextStr auf, welches alles ab #0 wieder abschneitet/löscht.


Da du ja wegen der (gewollten) #0 eh die Dateien mit 'nem eigenem Programm erstellen muß, wie wäre es dann mit der eingebauten Längenangabe? Dieses würde dann auch das einlesen beschleunigen/vereinfachen, da ja gleich bekannt wäre, wie lang der String wäre.

Also jeweils die Länge (LongInt) und nachfolgend den Stringinhalt speichern.

Sozusagen:
Delphi-Quellcode:
i := Length(S);
Write(@i, SizeOf(i));
Write(PChar(S), i);

Read(@i, SizeOf(i));
SetLength(S, i);
Read(PChar(S), i);
(womit eingelesen/gespeichert wird, is dir überlassen ... also ob Stream, oder was Anderes)

xZise 3. Apr 2007 09:36

Re: Datei mit "#0" schreiben?
 
So... Ich will jetzt mein Vorhaben genauestens beschreiben:
Es gibt ein Dateiformat, welches eigentlich ich nicht bestimmen kann. Ich kann eben nur darauf hoffen, dass der Programmierer "TStringList.LoadFromFile" benutzt.
Ich kam aber auf die Idee weitere Daten da zu hinterlegen. Wie macht man das ohne das Programm zu verwirren: Man tut so (für TStringList) so, als sei die Datei da zuende obwohl dahinter noch was ist, was es aber nicht interpretieren kann.

Deshalb habe ich gedacht, dass nach den Informationen, welche das Programm versteht, ein #0 zu setzten. Während mein Programm, welches auch damit arbeitet dies berücksichtigt und die Daten dahinter ausliest.

Deshalb kann ich das Format nur mit den #0 verändern.

Code:
[color=#0000ff]Datei[/color]
[color=#7f00ff]#0[/color]
[color=#00ff3f]Meine Daten[/color]
Das grüne kann ich ändern...
Und das Blaue kann ich nicht ändern...

Zitat:

Zitat von himitsu
@xZise: TStringList.LoadFromFile ließt die gesamte Datei ein, nur ruft es danach TStringList.SetTextStr auf, welches alles ab #0 wieder abschneitet/löscht.

Danke ;)

Zitat:

Zitat von himitsu
Da du ja wegen der (gewollten) #0 eh die Dateien mit 'nem eigenem Programm erstellen muß, wie wäre es dann mit der eingebauten Längenangabe? Dieses würde dann auch das einlesen beschleunigen/vereinfachen, da ja gleich bekannt wäre, wie lang der String wäre.

Geht eben nicht (s.o.)

Zitat:

Zitat von himitsu
Also jeweils die Länge (LongInt) und nachfolgend den Stringinhalt speichern.

Wenn dann nur für meinen Teil ;)

Zitat:

Zitat von Hansa
Stichwort : TInifile. Würde ich mir mal ansehen. Mit #0 oder WinApi am Betriebssystem rumzufummeln würde ich mir gründlich überlegen.

Geht eben nicht (s.o.)

[edit]Es stellt sich mir die Frage, wie ich ein #0 schreiben kann... mit TFileStream!
Das tuts net:
Delphi-Quellcode:
level.Write(Pointer(#0)^, Length(#0));
[/edit]

3_of_8 3. Apr 2007 10:14

Re: Datei mit "#0" schreiben?
 
Zitat:

Zitat von himitsu
@3_of_8: das mit dem abschließendem #0 in String hab ich nie bezweifelt

Naja, oben hast du gesagt "Nein, sind sie nicht." als Antwort auf meine Aussage, Delphi-Strings wären nullterminiert.


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:27 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz