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 Textdatei (txt) in Stringgrid einlesen (https://www.delphipraxis.net/143030-textdatei-txt-stringgrid-einlesen.html)

Pascall 8. Nov 2009 14:20


Textdatei (txt) in Stringgrid einlesen
 
Hey

Ich will etwas in einen Stringgrid einlesen aus einer Textdatei (*.txt).
Es geht darum Buchstaben + der zugehörigen Häufigkeit einzulesen. Dabei ist es wichtig, dass der Häufigste Buchstabe mit der Häufigkeit oben steht.
Die Häufigkeit und der Buchstabe sollen aber in getrennte Zeilen.

Vielleicht könnte man eine Textdatei nach diesem Muster erstellen:

A(17%)
B(2%)
C(4,5%)
...

Dabei die Buchstaben in das eine, die Zahlen in das andere einlesen. Was vermutlich viel aufwändiger wäre, dann noch alles nach größe zu sortieren. Daher ist es wohl besser die Zahlen schon in der Textdatei geordnet vorzuliegen zu haben.

Wichtig ist mir hierbei auch, dass ich gerne Denkanstöße annehme, jedoch nichts vorprogrammiert haben will. Ich weiß gar nicht wie man erwarten kann, wenn man sich Programmieren selber beibringt, gesagt zu bekommen: Benutze das und das.
Wenn man dann nochmal nachfragt heißt es gleich: Musst du schon selber machen. Den Lerneffekt verstehe ich dabei gar nicht. (War nicht hier)

Vielen Dank

Pascall

alzaimar 8. Nov 2009 15:08

Re: Textdatei (txt) in Stringgrid einlesen
 
Teile die Aufgabe auf:
1. Textdatei einlesen und Buchstaben zählen. Ausgabe z.B. mit WriteLn als konsolenanwendung.
2. Die Ausgabe (also das Ergebnis) sortieren.
2. Wenn das Ergebnis stimmt, dann die Ergebnisse in ein Stringgrid schreiben. Dazu musst du dann ein neues Projekt starten, kannst aber die Ergebnisse (den Code) aus 1 und 2 verwenden...

Luckie 8. Nov 2009 16:20

Re: Textdatei (txt) in Stringgrid einlesen
 
Was ist denn jetzt dein konkretes Problem? Was hast du schon an Code? Was erwartest du jetzt von uns?

p80286 9. Nov 2009 15:14

Re: Textdatei (txt) in Stringgrid einlesen
 
Hallo Pascall,

Ich würde es so lösen:
1) array [0..255] of integer
wobei jede Array-Zelle für einen Buchstabe/Zeichen steht.
mit 0 initialisieren.

2) Textdatei Zeichen für Zeichen lesen und das Zeichen als Index des Arrays verwenden und dann inc(a[ord(Zeichen)],1);
(natürlich gepuffert alles andere wäre zu langsam)

3) Im Stringgrid die erste Spale mit den Zeichen vorbelegen, in der zweiten Spalte die im Array gespeicherten Zählungen.

Gruß
K-H

Uwe Raabe 9. Nov 2009 15:51

Re: Textdatei (txt) in Stringgrid einlesen
 
Also, habe ich jetzt die Frage falsch verstanden?

Ich interpretiere das so, daß er den Inhalt des Stringgrids aus einer Textdatei laden will, in der die einzelnen Buchstaben zusammen mit ihrer Häufigkeit stehen. Wie diese Textdatei zustande kommt, hat damit gar nichts zu tun. Vielleicht gibt es ja solche Buchstabenhäufigkeitsdateien für verschiedene Sprachen oder sonstige Kriterien bereits.

Man könnte die Textdatei einfach nach dem Name=Value Prinzip aufbauen, einfach in eine Stringlist laden und daraus dann das Stringgrid füllen.

Delphi-Quellcode:
 
lst := TStringList.Create;
try
  lst.LoadFromFile(FileName);
  for I := 0 to lst.Count - 1 do begin
    StringGrid[0, I] := lst.Names[I];
    StringGrid[1, I] := lst.ValueFromIndex[I];
  end;
finally
  lst.Free;
end;

Pascall 10. Nov 2009 14:43

Re: Textdatei (txt) in Stringgrid einlesen
 
Hey

Folgendes:
Ich habe einen Stringgrid und will dort eine Textdatei einlesen.
Die Textdatei soll etwa so aussehen:


E (17,7)
A (35,7)
X (0,03)
B (33,6)


Dabei will ich die Buchstaben in die 4 Zeile einlesen und die Zahlen entsprechen passend in die 5. Zeile. Danach sollen Buchstaben + Zahlen sortiert werden (nach den Zahlen, aber Buchstaben müssen natürlich dabei bleiben) Das habe ich aber schon.

Mir fehlt nur noch das einlesen

Pascall

@ Uwe: Deinen Ansatz verstehe ich leider nicht, sorry: Loadfromfile ist klar, mit try und finally habe ich noch nie gearbeitet
@ p80286: Das mit dem puffern interessiert mich, ist das einfach zu programmieren? Das bräuchte ich nämlich auch noch für eine andere Sache...

p80286 10. Nov 2009 16:14

Re: Textdatei (txt) in Stringgrid einlesen
 
Hallo pascall,

das mit Try finally funktioniert so, daß wenn ein Fehler zwischen try und finally auftritt, die Verarbeitung sofort zur Anweisung nach finally springt.
In Uwes Beispiel befindet sich vor Finally der "Leseabschnitt" und hinter finally der "Aufräumabschnitt" der auf jeden Fall ausgeführt werden sollte. Man könnte darüber streiten ob das unbedingt notwendig ist, ein Fehler ist es aber auf keinen Fall, da dann sicher gestellt ist, daß z.B. lst wieder aus dem Speicher verschwindet.

[Edit]
wenn Die Daten so erfasst sind, wie Du beschrieben hast, dann kommst Du mit CommaText oder Value nicht weiter, dann mßt Du mit pos('(',...) die eingelesenen Zeilen auseinander nehmen.
[/Edit]

"Puffern":

Delphi-Quellcode:
const
  maxpuff = $FFFF;
var
  puffer : array [0..maxPuff] of byte;
  fs    : tfilestream;

...

fs:=tfilestream.create(MyFilename,myAttributes);
repeat
  gelesen:=fs.read(puffer,sizeof(puffer));
  for i:=0 to gelesen do
   //....verarbeite puffer[i] .........
until gelesen<>sizeof(puffer);
fs.free;
So in etwa sieht eine solche Leseroutine aus. Wobei für Dich der maxPuff der interessanteste Teil ist, da sollte man nicht zu sparsam sein. Puffer kann allerdings auch ein array of byte, oder array of char oder ... sein.
wichtig ist hier nur, daß Du das nicht zu klein wählst.


Gruß
K-H

DeddyH 10. Nov 2009 16:45

Re: Textdatei (txt) in Stringgrid einlesen
 
Ich würde mir einen Record oder noch besser eine Klasse deklarieren, die die zusammenhängenden Daten beinhaltet. Dann die Textdatei einlesen, die einzelne Zeile parsen und dem Record/der Klasse die Einzelwerte zuweisen. Die Records/Objekte werden dann in einer Liste verwaltet, sortiert und im StringGrid ausgegeben. Hier das Ganze einmal in Code gepackt:
Delphi-Quellcode:
uses math;

//Deklaration der Klasse
type
  TDatensatz = class
  private
    FBuchstabe: Char;
    FZahl: Double;
  public
    property Buchstabe: Char read FBuchstabe write FBuchstabe;
    property Zahl: Double read FZahl write FZahl;
  end;

//Sortierfunktion
function CompareFunc(Item1, Item2: Pointer): integer;
begin
  if SameValue(TDatensatz(Item1).Zahl, TDatensatz(Item2).Zahl) then
    Result := 0
  else if TDatensatz(Item1).Zahl < TDatensatz(Item2).Zahl then
    Result := -1
  else
    Result := 1;
end;

procedure TfrmStringGridDemo.Button1Click(Sender: TObject);
const Pfad = 'C:\Test\Test.txt'; //nur zum Testen hartkodiert
var aObject: TDatensatz;
    aList: TStringlist;
    i, FirstBracket, SecondBracket: integer;
    s: string;
begin
  //evtl. bereits enthaltene Objekte löschen
  FObjects.Clear;

  //Stringliste erzeugen und aus Datei einlesen
  aList := TStringlist.Create;
  try
    aList.LoadFromFile(Pfad);

    //Dafür sorgen, dass genügend Zellen im StringGrid verfügbar sind
    if (StringGrid1.ColCount - StringGrid1.FixedCols) < aList.Count then
      StringGrid1.ColCount := aList.Count + StringGrid1.FixedCols;
    if (StringGrid1.RowCount - StringGrid1.FixedRows) < 5 then
      StringGrid1.RowCount := StringGrid1.FixedRows + 5;

    //Datei zeilenweise auswerten, Objekt erzeugen, Werte zuweisen
    for i := 0 to aList.Count - 1 do
      begin
        aObject := TDatensatz.Create;
        if trim(aList[i]) <> '' then
          aObject.Buchstabe := trim(aList[i])[1];
        FirstBracket := Pos('(',aList[i]);
        SecondBracket := Pos(')',aList[i]);
        s := Copy(aList[i],FirstBracket + 1, SecondBracket - FirstBracket - 1);
        aObject.Zahl := StrToFloatDef(s,0);

        //... und der Liste hinzufügen
        FObjects.Add(aObject);
      end;

    //Liste sortieren
    FObjects.Sort(@CompareFunc);
    StringGrid1.Rows[StringGrid1.FixedRows + 3].BeginUpdate;
    StringGrid1.Rows[StringGrid1.FixedRows + 4].BeginUpdate;
    try
      //... und Werte in der StringGrid ausgeben
      for i := 0 to FObjects.Count - 1 do
        begin
          StringGrid1.Cells[StringGrid1.FixedCols + i,StringGrid1.FixedRows + 3] := TDatensatz(FObjects[i]).Buchstabe;
          StringGrid1.Cells[StringGrid1.FixedCols + i,StringGrid1.FixedRows + 4] := FloatToStr(TDatensatz(FObjects[i]).Zahl);
        end;
    finally
      StringGrid1.Rows[StringGrid1.FixedRows + 3].EndUpdate;
      StringGrid1.Rows[StringGrid1.FixedRows + 4].EndUpdate;
    end;
  finally
    //Stringliste wieder freigeben
    aList.Free;
  end;
end;

//mit dem Formular Objektliste erzeugen
procedure TfrmStringGridDemo.FormCreate(Sender: TObject);
begin
  FObjects := TObjectList.Create;
end;

//und am Ende entsorgen
procedure TfrmStringGridDemo.FormDestroy(Sender: TObject);
begin
  FObjects.Free;
end;

p80286 10. Nov 2009 17:00

Re: Textdatei (txt) in Stringgrid einlesen
 
@DeddyH

Ist die frühe Festlegung von RowCount und ColCount notwendig oder Dein pers. Stil?

Gruß
K-H

Pascall 10. Nov 2009 17:03

Re: Textdatei (txt) in Stringgrid einlesen
 
@DeddyH: So werde ich es vermutlich machen, danke

@ p80286: Danke, dass mit dem try + finally habe ich kapiert. Was sinnvolles neues gelernt =). Jedoch das mit dem Puffern ist wohl eine Nummer zu hoch für mich, da blicke ich überhaupt nicht durch. Trotzdem vielen Dank für den Versuch.

Bin ein Pascal Anfänger und das reicht mir auch erst Mal. Wenn ich die Schule beendet habe werde ich mich mit C++ vertraut machen und ich denke dafür reicht mein bisheriges kleines Wissen schon aus. Ein wirklich sehr nettes Forum hier, vielen Dank für eure ganze Hilfe.
Ich wette es war nicht das letzte Mal, dass ich hier geschrieben habe =)


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:58 Uhr.
Seite 1 von 2  1 2      

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