Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Schleife zum Auslesen eines Arrays geht nicht richtig


DelphiMarkus - Di 17.03.09 23:51
Titel: Schleife zum Auslesen eines Arrays geht nicht richtig
Hallo!
Ich weiß nicht mehr weiter. Seit 2 Tagen zerbreche ich mir den Kopf an einer Schleife und nun stelle ich auch noch fest, dass das nicht mein einziges Problem ist, denn die Schleife, die mir das Array anzeigen soll, funktioniert auch nicht richtig.
Vielleicht sehe ich aber auch den dicken Fehler nicht, der da drin ist...

Hier ein Ausschnitt:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
uses uDB;

{...}

procedure TfrmMain.FormShow(Sender: TObject);
begin

  {... Zur DB verbinden, Daten auslesen über SQL usw.}

  //Anzahl der Records zählen
  AnzahlRecord := qry1.RecordCount;
  {... Fällige Vokabeln auslesen}
end;

procedure TfrmMain.btn1Click(Sender: TObject);
var
  e: Integer;
  Text: string;
begin
  lbl1.Caption := '';
  LeseFacher;  // Aus uDB
  Fach[1] := 'k';
  Fach[2] := 'o';
  for e := 0 to 30 do
  begin
    Text := Text + Fach[e] + ',';
  end;
  lbl1.Caption := Text;
end;

Den Text aus uDB möchte ich ungern posten, da ist eh auch noch ein Fehler drin wieder mit ner Schleife...

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
unit uDB;

interface

uses SysUtils;
  {...}
  function LeseDBFeld(Nummer, Feld, Format: Integer): string;
  procedure LeseFacher();

  {...}

var
  Fach : array[0..30of string;
  FZaehler, NrFach, Fertig, GFertig : Integer;


implementation

uses Main;

{...}

//******************************************************************************
//**************************** Ließt die Fächer aus ****************************
//******************************************************************************
procedure LeseFacher(); //So viele Fehler sind da drin, denke ich ;) Zumindest klappt das nicht.
var
  i : Integer;
  TempFach : string;
begin
  Fertig := 0;
  GFertig := 0;
  NrFach := Fertig + 1;
  NrFach := 0;
  for FZaehler := 0 to 30 do
  begin
    Fach[FZaehler] := '';
  end;
  FZaehler := 0;
  for i := 0 to AnzahlRecord do 
  begin
    TempFach := LeseDBFeld(i,3,0);
    Fertig := 0;
    FZaehler := 0;
    // Ab hier stimmt was nicht!
    repeat // Ab hier bitte nicht zu ernst nehmen. Das ist Code, der 1000x umgeschrieben wurde in 2 Tagen um den Fehler zu finden.
      if (Fach[FZaehler] = TempFach) or (Fach[FZaehler] <> ''then
      begin
        Fertig := 1;
      end;
      if (Fach[FZaehler] <> TempFach) and (Fach[FZaehler] = ''then
      begin
        Fertig := 0;
      end;
      if (Fertig = 0and (GFertig = 0then
      begin
        Fach[FZaehler] := TempFach;
        Inc(NrFach);
        GFertig := 1;
      end;
      Inc(FZaehler);
      //Fertig := 0;
    until (FZaehler = 30or (GFertig = 1);
    // Bis hier
  end;
  Fertig := 0;
end;


So, jetzt kommt aber nicht etwa das richtige raus, wie z.B. 'English,k,o' sondern nur 'English'. Ich weiß gar nicht mehr weiter.
Langsam zweifle ich an meiner Kunst Schleifen zu schreiben und Fehler zu suchen... :hair:

Es wäre nett, wenn mir jemdand helfen könnte, denn ich weiß einfach keinen Ausweg.

Danke,
Maxi


LexXis - Mi 18.03.09 00:02

Da muss wohl wo anders der Wurm drin sein. Der von dir angegebene Codeabschnitt funktioniert einwandfrei :nixweiss:
Poste doch mal, was du statt {...} eigentlich in deiner Routine stehen hast.


DelphiMarkus - Mi 18.03.09 00:04

Hab ich mal gemacht.
Siehe 1. Post.

Edit:
Noch mehr Code hinzugefügt.

Edit2:
Hab noch ein paar Variablen vergessen mitzukopieren. Sind jetzt drin.


LexXis - Mi 18.03.09 00:13

Wird AnzahlRecord auch irgendwo ein Wert zugewiesen? Wenn nicht, wird die Schleife zum Auslesen ja nur einmal durchlaufen und somit nur das erste Fach "English" ausgelesen und in dein Fächer-Array übergeben!


DelphiMarkus - Mi 18.03.09 00:15

Ja, in TfrmMain.FormShow wird der Wert zugewiesen.

Außerdem klappt mit diesem Wert ja auch das Auslesen der Fälligen Vokabeln...

Edit:
Quelltext in 1. Post bearbeitet.


oldmax - Mi 18.03.09 08:05

Hi
Nun, so wie es aussieht, ist dir da ein kleiner Irrtum unterlaufen...


Delphi-Quelltext
1:
AnzahlRecord := qry1.RecordCount;                    

Diese Anweisung gibt dir die Anzahl der Datensätze, das ist richtig. Nehmen wir an, es sind 15....

Nun deine Schleife...

Delphi-Quelltext
1:
for i := 0 to AnzahlRecord do                    


Du fängst bei 0 an, das ist für eine Indizierung in der Regel auch richtig, aber du durchläufst die Schleife 16 mal, also dürfe einer deiner Zugriffe ins Nirwana gehen.

Richtig solte sein

for i := 0 to AnzahlRecord-1 do

Jetzt sind es entsprechend der Anzahl der Datensätze Durchläufe der Schleife.

Ich hab mir nicht die Mühe gemacht, deine Dateizugriffe näher zu betrachten und auch deine Codeschnipsel hab ich mir nicht näher angesehen.
Doch solche Konstrukte sind schnell fehlerbehaftet von der Logik her..


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
if (Fach[FZaehler] = TempFach) or (Fach[FZaehler] <> ''then
begin 
  Fertig := 1;      
end
if (Fach[FZaehler] <> TempFach) and (Fach[FZaehler] = ''then     
begin     
  Fertig := 0;      
end;

Bei deinem Code kann schnell ein Zustand eintreten, das keines der Beiden Ifs bearbeitet wird oder auch immer das letzte. Trifft hier zwar nichtz u, aber die Gefahr ist groß. Daher entweder mit else oder case arbeiten.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
if (Fach[FZaehler] = TempFach) or (Fach[FZaehler] <> ''then
begin 
  Fertig := 1;      
end else  
begin     
  Fertig := 0;      
end;


Deine Kommentare sind auch nicht hilfreich..
ab hier stimmt was nicht
ab hier nicht zu ernst nehmen
gaaanz toll........

Zur Fehlersuche solltest du aber mal den "roten Punkt" benutzen. ( Haltepunkte setzen) und dann Schrittweise mit F 7 durch dein Programm gehen. Dabei kannst du mit der Maus über den Variablen deren Werte lesen. Es sollte dir zeigen, wo du plötzlich falsche Ergebnisse bekommst.

Gruß oldmax


DelphiMarkus - Mi 18.03.09 08:16

Hallo,
das habe ich verschlafen mit dem AnzahlRecord - 1. Auch die Kommentare fehlen, die hab ich aber schon bei einigen anderen Funktionen gemacht. Und die Kommentare im Code oben, die sind nur dafür da, dass ich sehe, dass da noch ein Fehler ist. Das wollte ich etwas eingrenzen.
Sonst sehen meine Kommentare etwas sinniger aus. :mrgreen:

Aber das was mich irritiert ist folgendes:
Wennn Fach[0] := 'English' ist und ich für Fach[1] := 'k' und für Fach[2] := 'o'; mache, warum wird denn dann in der Schleife zum Anzeigen nur 'English' angezeigt?

Außerdem, benutze ich diesen roten Punkt auch schon 2 Tage lang. ;)

Wenn noch jemand eine Idee hat, warum das nicht geht, bitte melden.
Danke,
Maxi


ene - Mi 18.03.09 09:09

Also zumindest die 31 ',' solltest du herausbekommen. Aber wenn nur 'English' und nicht 'Englisch,' herauskommt, würde ich drauf tippen, dass der Fehler vorher passiert. Anstatt Schleife kannst du auch mal folgendens schreiben:


Delphi-Quelltext
1:
2:
Text:= Fach[0] + ',' + Fach[1] + ',' + Fach[2] + ',';
lbl1.Caption:= Text;


Dann wüsste man wenigstens, ob im Array auch richtige Werte stehen. Wenn das klappt, setzt du einen Haltepunkt in die for e:= 0 to 30 do-Schleife und kontrollierst Text und Fach[e].


DelphiMarkus - Mi 18.03.09 15:20

Hallo!

Das klappt ja auch nicht. Es kommt immer nur 'English' raus, nix mit Komma, oder gar k oder o...
Aber warum das so ist verstehe ich nicht.


Delphi-Quelltext
1:
2:
3:
4:
  Fach[1] := 'k';
  Fach[2] := 'o';
  Text := Fach[0] + ',' + Fach[1] + ',' + Fach[2];
  lbl1.Caption := Text;


So sieht der Text aus, der nur 'English' anzeigt. 'English' kommt aus Fach[0], das weiß ich, aber wo der Rest abbleibt, weiß ich nicht.


DelphiMarkus - Mi 18.03.09 15:25

GRML

Ich glaub ich habs...

Und zwar:

Delphi-Quelltext
1:
2:
// Fach[0]:
'English                                                                                                                                                                                                                                                        '

Und da das Label das nicht anzeigen kann, weil es alles in einer Zeile steht, sehe ich auch nichts.
Jetzt müsste ich nur noch die Leerzeichen wegbekommen. Wie ich gesehen habe stehen die so in der MDB drin.


ene - Mi 18.03.09 16:01

Wie wäre es mit Trim()?


DelphiMarkus - Mi 18.03.09 16:47

Danke!
Das hat geholfen, jetzt wird es richtig angezeigt und ich kann mich der katastrophalen Funktion namens LeseFacher(); zuwenden.

Gruß,