Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   liste in datei specihern (https://www.delphipraxis.net/82481-liste-datei-specihern.html)

-most- 14. Dez 2006 07:44


liste in datei specihern
 
hi,
also hab die aufgabe bekommen ein Programm zur Verwaltung von Artieln eines warenhauses zu programmieren. Es soll Einträge wie Artikelnummer, anzahl , preis etc. enthalten.
Mein problem ist nun folgendes. ich wollte das mit einer einfach verketteten Liste lösen. nur wie kann ich diese in einer Datei speichern? bzw. wieder aufrufen?

thnx

Zwixx 14. Dez 2006 07:55

Re: liste in datei specihern
 
naja, das klingt für mich eher wie eine Datenbankanwendung und nicht wie verkettete Listen. Dadurch hast du auch keine Probleme wenn es mal an Auswertungen oder ähnliches geht. Wenns was kostenloses an Datenbank sein soll, seh dir mal Firebird an, die gibst auch als Version die keinen Datenbankserver benötigt sondern standalone fähig ist.

marabu 14. Dez 2006 07:57

Re: liste in datei specihern
 
Herzlich willkommen in der Delphi-PRAXiS, -most-.

Ist das eine Übungsaufgabe für einen Schüler? Welche Vorkenntnisse hast du? Du musst den Hintergrund etwas beschreiben, sonst schicken wir dich aus Versehen in die Wüste...

Freundliche Grüße vom marabu

-most- 14. Dez 2006 21:24

Re: liste in datei specihern
 
vorkenntnisse sind 2 jahre informatik Unterricht...
spezieller is das dann einfach verkettete Listen, datenstrukturen etc .. also nicht sehr dolle alles ^^

Aufgabe lautet das ich nen programm für nen Warenhaus schreiben soll wo man artikel mit preis, artikelname artikelnummer etc. speichern, aufrufen und verändern kann! (speichern in ner Datei)
also ja es is ne schüler aufgabe!

muss ich da bei datenbakn-arbeit viel beachten???

marabu 17. Dez 2006 07:24

Re: liste in datei specihern
 
Hallo,

bei einer solchen Aufgabenstellung bekommst du doch in der Regel bestimmte Vorgaben. Zwischen dem Arbeiten mit einer Liste (Laden, Speichern, Bearbeiten) und einer Datenbankanwendung bestehen erhebliche Unterschiede - alleine schon was die notwendigen Vorkenntnisse betrifft.

Mein Vorschlag für dich: Speichere deine Liste als CSV-Datei und bearbeite sie in einem StringGrid. Eine Routine zum Speichern findest du als Einstiegshilfe hier. Schau dir dazu einmal die Delphi Online Hilfe zu TStringList genau an.

Man kann natürlich auch ohne jedes Verständnis für Datenbanken einfach datensensitive Komponenten (TDBEdit, ...) auf eine Form setzen, einen TDBNavigator und eine TDataSource dazu und (fast) fertig. Aber dann macht Delphi alles und du nichts. Ob das dem Lehrer gefällt?

Grüße vom marabu

DP-Maintenance 17. Dez 2006 10:35

DP-Maintenance
 
Dieses Thema wurde von "SirThornberry" von "Programmieren allgemein" nach "Object-Pascal / Delphi-Language" verschoben.

-most- 11. Jan 2007 07:34

Re: liste in datei specihern
 
so richtig versteh ichs aber dennoch nicht... wie füge ich ne tstringlist ein und mit welchen befehlen kann die datei verändern? bruch ich nun ne tstringlist oder nen stringgrid oder wie? aber trotzdem schonmal vielen dank für die hilfe hat mich zumindest etwas weiter gebracht

marabu 11. Jan 2007 07:46

Re: liste in datei specihern
 
Guten Morgen,

Zitat:

Zitat von -most-
... wie füge ich ne tstringlist ein ...

eine StringList ist keine visuelle Komponente. Zur Anzeige und Manipulation deiner Daten verwendest du dann eher ein StringGrid.

Zitat:

Zitat von -most-
... mit welchen befehlen kann die datei verändern? ...

wenn du ohne Datenbank arbeiten willst, dann wirst du alle Daten auf einen Rutsch in den Speicher einlesen und nach der Bearbeitung als Ganzes wieder wegschreiben. Dein Lehrer hat sicher keine mehrplatzfähige Lösung im Sinn.

Zitat:

Zitat von -most-
... Einträge wie Artikelnummer, anzahl , preis etc. ...

Das solltest du sehr genau wissen, bevor du überhaupt anfängst. Mach dir eine Tabelle:

Code:
Entität: Artikel

Attribut      Beschreibung
============== ====================================
Nummer        eindeutige Zahl mit 6 Stellen
Bezeichnung   maximal 100 Stellen
VKPreis       Verkaufspreis
Beschreibung  mehrzeiliger Text
Bestand       Vorratsmenge
etc.
Ohne eine solche Tabelle kann das Schreiben eines Programms schnell frustrierend werden. Wenn du alles zusammengestellt hast, kannst du das Ergebnis hier veröffentlichen und erhältst dann bei Bedarf weitere Hilfe.

Freundliche Grüße

-most- 18. Jan 2007 07:34

Re: liste in datei specihern
 
das verwirrt mich hier alles... erstmal muss ich sagen das ich keine ahnung habe! so ganz allgemein: ich bin unfähig. Was ich kann ist mit verketteten listen arbeiten, da hab ich alles was ich für diese aufgabe brauche (Nächsten eintrag, vorheriger eintrag,neues listenelement erstellen, listenelement löschen etc) nur leider wird das ja bei jedem programmstart gelöscht.Um nochmal vorn anzufangen: wie schaff ich es, das die listenelemente in einer datei gespeichert werden? ist das überhaupt möglich?

Hab ja versucht mich mit csv-dateien, Tstringlist usw auseinanderzusetzten aber wie das ganze letztendlich in einen quelltext bringe der dann sogar funktioniert weiß ich nicht... da fehlen mir warscheinlich die vorkenntnisse, weil die sind sehr gering. Speichern allegmeint hatte ich noch nie gehabt. Hab mir da was in unseren Dümmlichen lehrbuch durchgelesen, das half mir aber auch nich weiter...

das is jetzt hier mein letzter versuch, danach werd ich hier keinen mehr nerven (und ich weiß wie sehr sowas nerven kann :) )

marabu 18. Jan 2007 08:59

Re: liste in datei specihern
 
Tut mir leid, wenn ich dich verwirrt habe. Und du nervst auch ganz sicher nicht.

Natürlich kannst du auch eine verkettete Liste als CSV-Datei speichern:

Delphi-Quellcode:
type
  TArtikel = class
    Next: TArtikel;
    Nummer: Cardinal;
    Bezeichnung: String;
  end;

var
  ArtikelListe: TArtikel;

procedure Save(artikel: TArtikel; fn: TFileName);
var
  s, a: TStrings;
begin
  s := TStringList.Create;
  a := TStringList.Create;
  s.Add('"Nummer","Bezeichnung"'); // ...
  while Assigned(artikel) do
  begin
    a.Add(IntToStr(artikel.Nummer));
    a.Add(artikel.Bezeichnung);
    // ...
    s.Add(a.CommaText);
    a.Clear;
    artikel := artikel.Next;
  end;
  a.Free;
  s.SaveToFile(fn);
  s.Free;
end;

begin
  ArtikelListe := TArtikel.Create;
  with ArtikelListe do
  begin
    Nummer := 1;
    Bezeichnung := 'Handtuch';
    Next := TArtikel.Create;
  end;
  with ArtikelListe.Next do
  begin
    Nummer := 2;
    Bezeichnung := 'Mausefalle';
  end;
  Save(ArtikelListe, ChangeFileExt(ParamStr(0), '.txt'));
end.
Getippt und nicht getestet.

Ich habe das Listenelement TArtikel als class und nicht als record definiert, weil ich dann New() und Dispose() durch Create() und Free() ersetzen kann - was ich für didaktisch sinnvoll halte. Trotzdem habe ich versucht so nahe wie möglich an deiner über Zeiger verketteten Liste zu bleiben, damit du folgen kannst.

Freundliche Grüße

sirius 18. Jan 2007 09:01

Re: liste in datei specihern
 
Ok, wir versuchen es mal ohne irgendwelche Stringlisten, Objekte oder Datenbanken, sondern (wie früher :feuerchen: ) mit einer verketteten Liste und typisierten Dateien.

Dazu brauchst du zwei Funktionen/Prozeduren, eine um den gesamten Speicherinhalt mit einen Schwunf auf die Platte zuschreiben und eine für Platte-->Speicher. Das dürfte mit deinen vorkenntnissen das einfachste sein.

Code sagt manchmal mehr als tausend Worte: So stell ich mir das vor:

TypenDefinition:
Delphi-Quellcode:
type TDatensatz={packed} record
      Art_Nr:integer;
      //Hier alle Variablen für einen Artikel definieren
end;

//jetzt deine Liste (wie auch immer du die gerne machst)
type PItem=^TItem
     TItem=record
       next,prior:PItem;
       Artikel:TDatensatz;
end;
Soweit dazu. Und wie du jetzt prinzipiell mit Listen arbeitest, weist du ja, schreib ich jetzt nicht extra auf.
Das "packed" vor dem "record", kannst du auskommentieren, dadurch wird der benötigte Speicherplatz nachher auf der Platte etwas geringer, mit dem Nachteil, dass das Programm länger braucht. Allerdings wird beides bei dem zu erwartenden Programmeinsatz nicht bemerkbar sein -->deswegen ist es egal


Jetzt zum Speichern. eine typisierte Datei wird mit "file of [typ]" definiert und dann kannst du diesen Typ dort beliebig rein schreiben und lesen (günstigerweise nehmen wir als Typ useren record:
Delphi-Quellcode:
procedure alles_speichern;
var Datei:file of TDatensatz;
    item:PItem;
    //...
begin
  assignfile(Datei,'test.dat'); //Den Dateinamen kannst du natürlich auch vorher noch abfrage´n, oder sonstwo ablegen (mit Pfadangabe)
  rewrite(Datei); //hier wird die Datei neu erstellt, eine bereits vorhanden Date wird zuvor gelöscht
 
  item:=start; //start ist anfang der Liste
  while item<>nil do begin
    //hier musst du jetzt mit einer Schleife durch alle datensätze gehen
    //speichern tust du mit
    write(Datei,item^.Artikel);

    item:=item^.next;
  end;

  closefile(Datei); //schließen
end;


procedure alles_einlesen
var Datei:file of TDatensatz;
    item,tmp:PItem;
    //...
begin
 
  //hier Liste löschen

  assignfile(Datei,'test.dat');
  if fileexists('test.dat') then begin
    reset(Datei); //hier wird die Datei geöffnet
    start:=nil;
    item:=nil;
    while not eof(Datei) do begin //eof=end of file
      new(tmp);
      read(Datei,tmp^.Artikel); //einlesen
     
      //Liste vervollständigen
      if start=nil then start:=tmp;
      if item=nil then begin
        item:=tmp;
        item^.prior:=nil;
        item^.next:=nil;
      end else begin
        item^.next:=tmp;
        tmp.^prior:=item;
        item:=tmp;
      end;
    end;
    closefile(Datei); //schließen
  end else //Datei existiert nicht
end;
Du kannst auch nur einzelne Datensätze ändern. Mit "seek" kannst du auf den entsprechenden Datensatz springen.

-most- 18. Jan 2007 11:06

Re: liste in datei specihern
 
vielen vielen dank an euch bedie! das hat mir jetzt wirklich geholfen, denk ma den rest schaff ich alleine.
super!

-most- 25. Jan 2007 07:37

Re: liste in datei specihern
 
Was genau muss hier bei den pünktchen noch hinzugefügt werden? und was ist dieses "tmp"

Delphi-Quellcode:
var Datei:file of TDatensatz;
    item,tmp:PItem;
    //...
und wasgenau ist hier zu beachten?
Delphi-Quellcode:
item:=start;
  while item<>nil do begin
    start:=start^.next;
     write(Datei,item^.Artikel);
    item:=item^.next;
  end;
reicht das so? oder wie in etwa muss diese schleife aussehen?


danke wa

Mavarik 25. Jan 2007 08:02

Re: liste in datei specihern
 
Hallo!

Ich kann mich noch gut an meinen Informatik Unterricht erinnern.

Es werden immer Programme geschrieben die an den Haaren herbeigezogen werden...

Geht es bei Deinem Programm und die Listenverkettung oder um die Datei?

Eine Struktur Deiner Größe musste früher auf dem Heap abgelegt werden, da im Datensegment
nie genug Platz war. Außerdem war der Heap früher defragmentiert und hatte ggf. nicht genug Platz
um die Daten linear zu speichern.

Heute sieht es eher so aus...(Schlampigerweise) :oops:

Delphi-Quellcode:
Const
   MaxArtikel = 100000;

type
   TWarenhaus = Record
                  ArtikelNr : String[40];
                  //...
                end;
Var
   Waren : Array[0..MaxArtikel] of TWarenhaus;
Frank :coder:

sirius 25. Jan 2007 09:49

Re: liste in datei specihern
 
Zitat:

Zitat von -most-
Was genau muss hier bei den pünktchen noch hinzugefügt werden? und was ist dieses "tmp"
Delphi-Quellcode:
var Datei:file of TDatensatz;
    item,tmp:PItem;
    //...

Bei den Pünktchen...? Hmm, anscheinend nix mehr, ausser du brauchst zum Löschen noch ein paar Variablen.

Und wozu ich tmp brauche. Um mir mal kurz ne Addresse zu merken.
Ok, ein bischen ausführlicher zu Adressen/Zeigern/Pointern:
tmp hab ich angelegt, weil ich es nachher brauche. item und tmp sind ja "nur" Zeiger. Belegen jeweils 4 Bytes auf dem Stack und zeigen irgendwohin in den Hauptspeicher. Und wenn wir alles richtig gemacht haben (mit der Zuweisung etc.) zeigen sie auf unseren Record. Was macht der Compiler da nun genau? (Wir vernachlässigen mal das es virtuelle und reale Adressräume gibt, das ist jetzt nicht so wichtig und würde nur verwirren)
Nehmen wir an item zeigt auf eine Speicheradresse mit der Nummer 10. Dann steht genau die 10 in item drin (item = 10). Wenn ich aber den Inhalt von item haben will, dann ist mir die 10 relativ wurscht/schnuppe/egal. Deswegen mach ich da so ein Zeichen (^) drann. Das sagt dem Compiler ich will den Inhalt an Stelle 10 im Hauptspeicher haben (item^ = unser TItem). Das ist allerdings ein record und da gehts noch ein bisschen weiter. Ich möchte nämliche item^.next; Für Delphi heisst es ich will die Zahl (die ist auch wieder ein Zeiger immer 4 Bytes groß) an Stelle 10+0 im Hauptspeicher. Das "+0" Kommt daher, da "next" das erste Element ist. ein Zweites element im Record würde an Stelle 10+4 liegen (4 Bytes wegen dem next) usw...
Wenn ich jetzt tmp:=item mache. Dann schreibt er die Adresse 10 in die Variable tmp rein. Jetzt zeigen also tmp und item auf die selbe Stelle im Speicher. tmp=item=10. Ich kann also jetzt mit tmp^.next genau dieselbe Zahl lesen wie mit item^.next. Und wenn ich in z.b. item^.next:=211 ändere (was mit pointer allerdings nicht so einfach geht), ist diese Zahl auch genauso in tmp^.art_nr=211. die beiden Zeiger (tmp und item) zeigen ja auf dieselbe Addresse.
So ist das mit Zeigern. Und mit new(item) bekomme ich vom Speichermanager so eine frei Addresse. Mit dispose sage ich, dass ich die Addresse 10 (und die nachfolgenden n Bytes) nicht mehr brauche.

Zitat:

Zitat von -most-
und wasgenau ist hier zu beachten?
Delphi-Quellcode:
item:=start;
  while item<>nil do begin
    //start:=start^.next; rausnehmen
     write(Datei,item^.Artikel);
    item:=item^.next;
  end;
reicht das so? oder wie in etwa muss diese schleife aussehen?

Ich glaube ich hatte schon alles geschrieben, macnhmal bedeuten Kommentare bei mir auch, dass ich schon alles gemacht habe. Aber wenn du etwas an deinem Datensatz änderst, dann musst du auch da etwas ändern.

-most- 22. Feb 2007 06:56

Re: liste in datei specihern
 
Zitat:

Hallo!

Ich kann mich noch gut an meinen Informatik Unterricht erinnern.

Es werden immer Programme geschrieben die an den Haaren herbeigezogen werden...

Geht es bei Deinem Programm und die Listenverkettung oder um die Datei?

Eine Struktur Deiner Größe musste früher auf dem Heap abgelegt werden, da im Datensegment
nie genug Platz war. Außerdem war der Heap früher defragmentiert und hatte ggf. nicht genug Platz
um die Daten linear zu speichern.

Heute sieht es eher so aus...(Schlampigerweise)


1
·
·
·
5
·
·
·
·
10
Const
MaxArtikel = 100000;

type
TWarenhaus = Record
ArtikelNr : String[40];
//...
end;
Var
Waren : Array[0..MaxArtikel] of TWarenhaus;



Frank



:-D das ist ja schön und gut aber was hilft mir das jetzt??? :shock:

übrigens danke sirius

-most- 8. Mär 2007 07:46

Re: liste in datei specihern
 
so ich geb auf. ich habs jetzt ewigkeiten versucht (auch mit hilfe diverser tutorials) und bekomms einfach nicht hin. Wär jemand von euch evt. so nett mir des programm komplett zu schreiben? würd mich auch (soweit das im internet möglich ist) auch irgendwie erkenntlich zeigen. im endeffekt gehts hier nämlich um meine abi-note :wall:

danke schonma im voraus

sirius 8. Mär 2007 08:08

Re: liste in datei specihern
 
Na das ist ja schön und gut. Ich würde gern mal auf die schnelle Millionär werden :mrgreen:

Aber denkst du nicht auch, dass die Abi-Note deine Leistung wiederspiegeln soll. Und wenn du auf das Programm halt keine 15 Punkte bekommst, sondern nur 10 (je nachdem wie weit du gekommen bist), dann sollte das doch in Ordnung sein.

Im übrigen haben wir doch verschiedene (teils vollständige) Lösungsvorschläge zu deiner frage gepostet. Was sollen wir denn noch machen?


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:33 Uhr.

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