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 ASCII-Zeichen aus einer Datei auslesen (https://www.delphipraxis.net/83916-ascii-zeichen-aus-einer-datei-auslesen.html)

xZise 8. Jan 2007 15:26


ASCII-Zeichen aus einer Datei auslesen
 
Ich habe eine Datei, die z.B. so aussieht:
Zitat:

Ein kleiner Text
#0#0#0#0
#0#2#1#0
#0#3#0#0
#6#6#6#6
#6#0#0#6
#6#0#0#6
#6#6#6#6
Und nun möchte ich dass er das in ein 3D - Array schreibt:
Delphi-Quellcode:
daten : array of array of array of Byte
daten[1]
Zitat:

0000
0210
0300
daten[2]
Zitat:

6666
6006
6006
Aber es gibt ein Problem beim 1. ASCII-Zeichen: Es ist ein EOF-Marker, wie kann ich nun darüberhinaus auslesen?
Oder gibt es eine möglichkeit ein array platzsparend abzuspeichern. Ich brauch auch maximal nur 6 Bit ( = 64 "Zahlen") pro array-Item. Aber 8 Bits passen ja gut, weil ich das einfach über ASCII-Zeichen umwandeln kann...

sakura 8. Jan 2007 15:29

Re: ASCII-Zeichen aus einer Datei auslesen
 
Nutze doch einfach einen TFileStream und dann geht es in etwa so:
Delphi-Quellcode:
with TFileStream.Create(FileName, foOpenRead) do
try
  while Position < Size do
  begin
    // und einfach auslesen...
  end;
finally
  Free;
end;
...:cat:...

mkinzler 8. Jan 2007 15:29

Re: ASCII-Zeichen aus einer Datei auslesen
 
Versuch mal die Datei als Binärdatei anzusehen.

xZise 8. Jan 2007 15:35

Re: ASCII-Zeichen aus einer Datei auslesen
 
Zitat:

Zitat von sakura
Delphi-Quellcode:
with TFileStream.Create(FileName, foOpenRead) do
try
  while Position < Size do
  begin
    // und einfach auslesen...
  end;
finally
  Free;
end;

Und "inc(Position)" ist ein Byte "weiter"?

Zitat:

Zitat von mkinzler
Versuch mal die Datei als Binärdatei anzusehen.

Wie programmiert man das am besten?

[edit]Ich habe folgenden Code gefunden:
Delphi-Quellcode:
const
  LEVELS = 4;
  ROWS = 12;
  COLS = 12;

type
  TDimArray = array [0..3] of Byte;
  TMatrix = packed array of array of array of Byte;

procedure RedimMatrix(var m: TMatrix; dim: array of Byte);
begin
  SetLength(m, LEVELS, ROWS, COLS);
end;

procedure SaveMatrix(m: TMatrix; fn: TFileName);
var
  dwDim, dwSize: Cardinal;
begin
  dwDim := (Length(m) shl 8 + Length(m[0])) shl 8 + Length(m[0, 0]);
  dwSize := Length(m) * Length(m[0]) * Length(m[0, 0]);
  with TFileStream.Create(fn, fmCreate) do
  try
    Write(dwDim, SizeOf(dwDim));
    Write(m[0], dwSize); // korrigiert
  finally
    Free;
  end;
end;

procedure LoadMatrix(var m: TMatrix; fn: TFileName);
var
  dwDim, dwSize: Cardinal;
  dim: TDimArray absolute dwDim;
begin
  with TFileStream.Create(fn, fmOpenRead or fmShareDenyWrite) do
  try
    Read(dwDim, SizeOf(dwDim));
    // SetLength(m, Hi(dwDim), Lo(dwDim) shr 8, dwDim and $FF); // fehlerhaft
    SetLength(m, dim[2], dim[1], dim[0]);
    dwSize := Length(m) * Length(m[0]) * Length(m[0, 0]);
    Read(m[0], dwSize); // korrigiert
  finally
    Free;
  end;
end;

{
procedure TestMatrix;
const
  FN = 'c:\daten\dp\map.f2m';
var
  m: TMatrix;
  iLevel, iRow, iCol: Integer;
begin
  RedimMatrix(m, [LEVELS, ROWS, COLS]);
  for iLevel := Low(m) to High(m) do
    for iRow := Low(m[0]) to High(m[0]) do
      for iCol := Low(m[0, 0]) to High(m[0, 0]) do
        m[iLevel, iRow, iCol] := 48 + iLevel * 4 + iRow * iCol mod 10;
  SaveMatrix(m, fn);
  FillChar(m, SizeOf(m), 0);
  LoadMatrix(m, fn);
end;
}

procedure TestMatrix;
const
  FN = 'c:\daten\dp\map.f2m';
var
  m: TMatrix;
  iLevel, iRow, iCol: Integer;
  dwSize: Cardinal;
  okay: Boolean;
begin
  RedimMatrix(m, [LEVELS, ROWS, COLS]);
  dwSize := LEVELS * ROWS * COLS;
  for iLevel := Low(m) to High(m) do
    for iRow := Low(m[0]) to High(m[0]) do
      for iCol := Low(m[0, 0]) to High(m[0, 0]) do
        m[iLevel, iRow, iCol] := 48 + iLevel * 4 + iRow * iCol mod 10;
  SaveMatrix(m, fn);
  FillChar(m[0], dwSize, 0);
  LoadMatrix(m, fn);
  okay := True;
  for iLevel := Low(m) to High(m) do
    for iRow := Low(m[0]) to High(m[0]) do
      for iCol := Low(m[0, 0]) to High(m[0, 0]) do
        if m[iLevel, iRow, iCol] <> 48 + iLevel * 4 + iRow * iCol mod 10 then
          okay := False;
  WriteLn(IfThen(okay, 'fine', 'rats'));
end;
Aber der funktioniert in abgewandelter Form nicht mehr.
Delphi-Quellcode:
const
  LEVELS = 2;
  ROWS = 12;
  COLS = 12;

type
  TDimArray = array [0..3] of Byte;
  TMatrix = packed array of array of array of Byte;

procedure RedimMatrix(var m: TMatrix; dim: array of Byte);
begin
  SetLength(m, LEVELS, ROWS, COLS);
end;

procedure SaveMatrix(m: TMatrix; fn: TFileName);
var
  dwDim, dwSize: Cardinal;
begin
  dwDim := (Length(m) shl 8 + Length(m[0])) shl 8 + Length(m[0, 0]);
  dwSize := Length(m) * Length(m[0]) * Length(m[0, 0]);
  with TFileStream.Create(fn, fmCreate) do
  try
    Write(dwDim, SizeOf(dwDim));
    Write(m[0], dwSize); // korrigiert
  finally
    Free;
  end;
end;

procedure LoadMatrix(var m: TMatrix; fn: TFileName);
var
  dwDim, dwSize: Cardinal;
  dim: TDimArray absolute dwDim;
begin
  with TFileStream.Create(fn, fmOpenRead or fmShareDenyWrite) do
  try
    Read(dwDim, SizeOf(dwDim));
    // SetLength(m, Hi(dwDim), Lo(dwDim) shr 8, dwDim and $FF); // fehlerhaft
    SetLength(m, dim[2], dim[1], dim[0]);
    dwSize := Length(m) * Length(m[0]) * Length(m[0, 0]);
    Read(m[0], dwSize); // korrigiert
  finally
    Free;
  end;
end;

procedure TestMatrix;
const
  FN = 'c:\map.f2m';
var
  m: TMatrix;
  iLevel, iRow, iCol: Integer;
  dwSize: Cardinal;
  okay: Boolean;
begin
  RedimMatrix(m, [LEVELS, ROWS, COLS]);
  dwSize := LEVELS * ROWS * COLS;
  Form1.Memo1.Text := '';
  for iLevel := Low(m) to High(m) do
    for iRow := Low(m[0]) to High(m[0]) do
    begin
       Form1.Memo1.Text := Form1.Memo1.Text + #13#10;
      for iCol := Low(m[0, 0]) to High(m[0, 0]) do
      begin
        m[iLevel, iRow, iCol] := Random(256);
        Form1.Memo1.Text := Form1.Memo1.Text + ' ' + IntToStr(m[iLevel, iRow, iCol]);
      end;
    end;

  SaveMatrix(m, fn);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  TestMatrix;
end;

procedure TForm1.Button2Click(Sender: TObject);
const
  FN = 'c:\map.f2m';
var
  m: TMatrix;
  iLevel, iRow, iCol: Integer;
  dwSize: Cardinal;
  okay: Boolean;
begin
  LoadMatrix(m, fn);
  Form1.Memo1.Text := '';
  for iLevel := Low(m) to High(m) do
    for iRow := Low(m[0]) to High(m[0]) do
    begin
       Form1.Memo1.Text := Form1.Memo1.Text + #13#10;
      for iCol := Low(m[0, 0]) to High(m[0, 0]) do
      begin
        Form1.Memo1.Text := Form1.Memo1.Text + ' ' + IntToStr(m[iLevel, iRow, iCol]);
      end;
    end;
end;

end.

xZise 10. Jan 2007 08:40

Re: ASCII-Zeichen aus einer Datei auslesen
 
Hat keiner einen Fehler gesehen??

marabu 10. Jan 2007 11:31

Re: ASCII-Zeichen aus einer Datei auslesen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo Fabian,

der Code war von mir und nicht gut getestet. Schlimmer noch ist, dass er vom Ansatz her nicht funktioniert, da mehrdimensionale dynamische Arrays wohl nicht dicht gepackt werden. Als Wiedergutmachung hänge ich dir eine Demo an, die zumindest bei meinen ersten Tests funktioniert hat.

Freundliche Grüße

xZise 12. Jan 2007 14:57

Re: ASCII-Zeichen aus einer Datei auslesen
 
Danke marabu! Scheint zu funktionieren!

xZise 13. Jan 2007 19:51

Re: ASCII-Zeichen aus einer Datei auslesen
 
So ich habe nun ein weiteres Problem!
Und zwar habe ich in der ersten Zeile einen String.

Was müsste ich dann an marabus Code modifizieren, dass es einen String in der 1. Zeile hat?

marabu 14. Jan 2007 13:58

Re: ASCII-Zeichen aus einer Datei auslesen
 
Hallo Fabian,

von deinem Dateimuster in Beitrag #1 musst du ja schon abrücken, wenn du meinen Code verwenden möchtest. Ich erwarte die Dimensionsangaben vor dem Binärteil, damit ich das aufnehmende Array entsprechend dimensionieren kann. Für die vorangestellte Textzeile würde ich eine Standardlänge (z.B. 64 Byte) festlegen, auf den ersten 63 Byte den mit null oder blank characters aufgefüllten String speichern und bei Offset 63 (das 64. und letzte Byte) noch ein EOF (#26) setzen. Damit kannst du den String beim Laden problemlos überlesen und wer die Datei auf der Konsole anschaut, der sieht nur die ersten 63 Byte.

Grüße vom marabu

xZise 15. Jan 2007 19:03

Re: ASCII-Zeichen aus einer Datei auslesen
 
Und dein Code? Wie bringe ich ihn dazu nur ab den 65. Byte zu lesen?

Und übrigens: Wie kann ich da eigentlich 64 Chars "vorsetzen"?
Also einfach über TStringList:
Delphi-Quellcode:
sl := TStringList.Create;
sl.add(Name);
sl.SaveToFile(Path);
sl.Free;
bm := TByteMap.Create;
bm.Load(Path);
...


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:52 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 by Thomas Breitkreuz