Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Zeiger/Pointer Frage (grosse Arrays) @cracks (https://www.delphipraxis.net/43638-zeiger-pointer-frage-grosse-arrays-%40cracks.html)

Kendor 6. Apr 2005 19:05


Zeiger/Pointer Frage (grosse Arrays) @cracks
 
guten abend!

einführung:
-------------------
also ich habe einen xml parser, mit welchem ich mehrere files auslesen will.
die ausgelesenen informationen speichere ich dabei in ein grosses array (wollte es dynamisch machen und immer der grösse anpassen, das gibt aber speicherfehler ab einer grösse von 1002 einträgen) also... array[1..9999] of TDokument;
Delphi-Quellcode:
type TDocument = record
      ID: cardinal;
      Number: string;
      Title: string;
      usw..
      end;
jedes mal wenn nun der parser einen content zwischen zwei xml tag findet wird ein ereignis aufgerufen... ich habe zuvor das aktuelle xml tag in der globalen variable CurrTag gespeichert.

nun frage ich nach tag ab (btw. gibts keine möglichkeit auch nach strings eine case abfrage zu machen? wie c++?) (content beinhaltet den eintrag zwischen den tags)
Delphi-Quellcode:
      if CurrTag='ID' then
        begin
          CurrID:=strtoint(Content);  {/ ID ist immer erster eintrag daher geht das so }
            {  If CurrID>Length(NewDocDb) then SetLength(NewDocDb,CurrID+1); // geht nicht - speicher nehm ich an..? }
          NewDocDb[CurrID].ID:=strtoint(Content);
        end;  
     if CurrTag='Number' then
        NewDocDb[CurrID].Number:=Content;
     if CurrTag='Title' then
        NewDocDb[CurrID].Title:=Content;

      usw...
wie ihr seht ist das dann alles schön in meiner struktgur gespeichert... -> funktioniert alles bestens...

nun parse ich aber ein weiteres file, mit dem gleichen parser, den gleichen tags..
dieses will ich aber nicht in NewDocDB speichern, sondern in OldDocDB

frage:
-------------------------
wie kann ich das vereinfacht machen durch einen pointer?
also damit es etwa so aussieht:

Delphi-Quellcode:
if aktuelles file = altes file then
speicher_mich_hier = zeiger auf das array wo das alte gespeichert wird
if aktuelles file = neues file then
speicher mich hier = zeiger auf das array wo das neue gespeichert wird

      if CurrTag='ID' then
        begin
          CurrID:=strtoint(Content);
          speicher_mich_hier[CurrID].ID:=strtoint(Content);
        end;  
     if CurrTag='Number' then
        speicher_mich_hier[CurrID].Number:=Content;
     if CurrTag='Title' then
        speicher_mich_hier[CurrID].Title:=Content;

      usw...

vielleicht noch zu sagen: die arrays sind global... müssen...
klar geht das ganze auch indem man einfach die ganze abfrage kopiert und so für eine simple abfrage riesenviel code braucht...
aber ich denk es muss doch möglich sein? also eine referenz auf ein anderes array zu machen

vielen dank für eure schnellen antworten!
beste grüsse,
ein etwas verzweifelter kendor

Binärbaum 6. Apr 2005 19:15

Re: Zeiger/Pointer Frage (grosse Arrays) @cracks
 
Zitat:

Zitat von Kendor
nun frage ich nach tag ab (btw. gibts keine möglichkeit auch nach strings eine case abfrage zu machen? wie c++?) (content beinhaltet den eintrag zwischen den tags)

Hi,
von Haus aus kann man case nicht mit Strings verwenden, höchstens mit Char.
Allerdings ist es mit einem Trick doch möglich, case auf Strings anzuwenden. Dazu braucht man eine zusätzliche Funktion:
Delphi-Quellcode:
function StrIdx(aStr: string; strArr: array of string): Integer;
var i: Integer;
begin
  Result:= -1;
  for i:= 0 to High(strArr) do
    if (aStr=strArr[i]) then
    begin
      Result:= i;
      Break;
    end;
end;
Danach kann man folgendes verwenden:
Delphi-Quellcode:
const AlleMeineStrings: array [0..100] of string = ( 'ID', 'Number', ... );
...

begin
  ...
  case StrIdx(CurrTag, AlleMeineStrings) of
    0: ShowMessage('ID-Tag');
    1: ShowMessage('Number-Tag');
    2: ShowMessage('NochEin-Tag');
    ...
    -1: ShowMessage('Kein Tag');
  end;
end;
MfG
Binärbaum

Kendor 6. Apr 2005 21:44

Re: Zeiger/Pointer Frage (grosse Arrays) @cracks
 
hi binärbaum...
vielen dank. ist doch schonmal was :) werd ich gleich mal einführen.

und zur eigentlichen frage: niemand eine idee?

SirThornberry 6. Apr 2005 21:47

Re: Zeiger/Pointer Frage (grosse Arrays) @cracks
 
eignetlich hast du ja schon die lösung selbst gepostet:
Delphi-Quellcode:
if aktuelles file = altes file then
speicher_mich_hier = zeiger auf das array wo das alte gespeichert wird
if aktuelles file = neues file then
speicher mich hier = zeiger auf das array wo das neue gespeichert wird
derzeit verwendest du ja
Delphi-Quellcode:
array[1..9999] of TDokument
Mach daraus einfach einen neuen Typ und legen einen Pointer auf diesen Typ an. Und dann diesen Pointer typ verwenden.
Delphi-Quellcode:
  TDokumentArr = array[1..9999] of TDokument;
  PDokumentArr = ^TDokumentArr;

Kendor 6. Apr 2005 23:12

Re: Zeiger/Pointer Frage (grosse Arrays) @cracks
 
Zitat:

Zitat von SirThornberry
Mach daraus einfach einen neuen Typ und legen einen Pointer auf diesen Typ an. Und dann diesen Pointer typ verwenden.
Delphi-Quellcode:
  TDokumentArr = array[1..9999] of TDokument;
  PDokumentArr = ^TDokumentArr;

mmh, ich hab scheinbar grad einen rechten knopf :) wie geh ich denn da weiter vor?

ich hab mir das weiter überlegt, ungefähr so:
Delphi-Quellcode:

type TDocument = record
      ID: cardinal;
      Number: string;
      Title: string;
      usw..
      end;

var                                     // global
  OldDocDB: array[1..9999] of TDocument;
  NewDocDB: array[1..9999] of TDocument;
  EditDocDB: Pointer;                
  first_time_flag: bool;


procedure ich_werde_bei_content_aufgerufen(Sender, Content, ...);
begin

if aktuelles_file = altes_file and first_time_flag=0 then
begin
  EditDocDB = @OldDocDB;
  first_time_flag=1;
end;
if aktuelles_file = neues_file and first_time_flag=0 then
  EditDocDB = @NewDocDB;
  first_time_flag=1;
end;

if CurrTag='Number' then TDocument(EditDocDB[CurrID]^).Number:=Content;
if CurrTag='Title' then TDocument(EditDocDB[CurrID]^).Title:=Content;
usw...

end;
(first_time_flag benutze ich, dass nur beim ersten durchlauf der Pointer gesetzt wird, sonst wird doch jedes mal wieder an die erste stelle verwiesen?)

kann das so funktionieren?
damit ich in OldDocDB die einträge des alten files und in NewDocDB die des neuen habe?


vielen dank...

SirThornberry 6. Apr 2005 23:29

Re: Zeiger/Pointer Frage (grosse Arrays) @cracks
 
ich hab das gefühl das wir ananeinder vorbei reden/schreiben.
Ich hab das ganze so verstanden. Du hast 2 Arrays vom gleichen Typ. Und dann hast du eine Procedure die mit einem Array etwas anstellt. Dann willst du anhand einer Bedingung entweder das eine oder das andere Array auf die procedure anwenden?! richtig so?

Kendor 6. Apr 2005 23:33

Re: Zeiger/Pointer Frage (grosse Arrays) @cracks
 
genau :D
deine idee scheint gut zu sein nur hab ich atm keine ahnung wie ich denn das machen soll?

SirThornberry 6. Apr 2005 23:38

Re: Zeiger/Pointer Frage (grosse Arrays) @cracks
 
Ok dann nochmal (ausschnitt)
Delphi-Quellcode:
type
  TDocumentArray = array[1..9999] of TDocument;
  PDocumentArray = ^TDocument;
[...]
var                                     // global
  OldDocDB: TDocumentArray;
  NewDocDB: TDocumentArray;
  EditDocDB: PDocumentArray;                
  first_time_flag: bool;
[...]
if Bedingung then
  EditDocDB = @OldDocDB
else
  EditDocDB = @NewDocDB;

//Do something width EditDocDB

Kendor 6. Apr 2005 23:41

Re: Zeiger/Pointer Frage (grosse Arrays) @cracks
 
mmh *nickt* - könnt dich umarmen... - danke!... und jetzt kann ich beruhigt schlafen gehen ;)


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:27 Uhr.

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