Wie definiere ich dann "i" ? Ist es durch die Fragenanzahl zu ersetzen?
Ja, aber du weißt im Allgemeinen doch nicht, wieviele Fragen in der Datei stehen. Am besten arbeitest du mit einem dynamischen Array (aFragen: array of fragen), startest mit Array-Länge 0 und erhöhst die Array-Lange vor jedem Datensatz um 1 (es geht auch besser, aber das würde dich hier nur verwirren). Und beachte, dass die Indizierung eines dynamischen Arrays bei 0 beginnt. So sollte die Leseroutine in unit3 funktionieren (nicht getestet):
Code: Alles auswählen
var
afrage: array of fragen
procedure TForm3.B_starttestClick(Sender: TObject);
var i:integer;
begin
SetLength(afragen, 0); // wp
RG_frage.visible:=true;
RB_1.Visible:=true;
RB_2.Visible:=true;
RB_3.Visible:=true;
B_starttest.visible:=false;
punkte:=0; //Punkte-Startwert festlegen
fnr:=1; //FragenNummer auf 1 setzen
assignfile(datei,'fragen.db'); //die .db-Datei wird der Variable "datei" zugewiesen
reset(datei); //Öffnen der Datei zum Lesen
i:=0;
seek(datei,0);
while not eof(datei) do begin //Auslesen der "fragen.db"-Datei mit Schleife
seek(datei,i); //Datensatzzeiger setzen
read(datei,datensatz); //Lesen eines Datensatzes
SetLength(afragen, i+1); // wp: Platz im Array für neue Frage schaffen
afragen[i].frtext:=datensatz.frtext; //Belegung des zuvor definierten Records mit den Daten aus der "fragen.db"-Datei
afragen[i].a1:=datensatz.a1;
afragen[i].a2:=datensatz.a2;
afragen[i].a3:=datensatz.a3;
afragen[i].richtig:=datensatz.richtig;
fnr:=1;
punkte:=0;
i:=i+1; // wp: Zähler hochzählen. Steht jetzt am Ende, weil die Indizierung des Arrays bei 0 beginnt.
end;
closefile(datei); //Datei schließen
// wp: Im folgenden wird Index 1 durch 0 ersetzt
RG_frage.Caption:=afragen[0].frtext; //Füllen der Überschrift der RadioGroup mit der Frage Nr. 1 aus der Datei
RB_1.Caption:=afragen[0].a1; //Füllen des 1. Radiobuttons mit der Antwort Nr. 1 zur Frage 1 aus der Datei
RB_2.Caption:=afragen[0].a2; //Füllen des 2. Radiobuttons mit der Antwort Nr. 2 zur Frage 1 aus der Datei
RB_3.Caption:=afragen[0].a3; //Füllen des 3. Radiobuttons mit der Antwort Nr. 3 zur Frage 1 aus der Datei
B_pruefen.Visible:=true;
end;
Zur 2. Frage: Ich würde alles in eine Datei schreiben, ein Record pro Teilnehmer. Wenn du die Ergebnisse eines Teilnehmers abspeichern willst, musst du zuerst suchen ob dieser schon eingetragen ist und den Datensatz überschreiben. Es gibt bessere Methoden, aber du hast mit klassischen Dateien angefangen, dann könntest du so vorgehen:
Code: Alles auswählen
procedure TForm3.B_auswertungClick(Sender: TObject);
const
DATEINAME = 'ergebnisse.txt'; // wird öfter verwendet!
type
// Das ist der Record, der in die Datei geschrieben wird. Wichtig ist, dass die Größe konstant ist
TAntworten = record
vname:string[30];
nname:string[40];
ant_geg:string[30];
punkte_err:integer;
end;
var
p: Integer;
antworten: TAntworten;
begin
Showmessage('Congratulations! You reached '+inttostr(punkte)+' points.');
assignfile(datei_antworten,DATEINAME);
// Wenn's die Antwortendatei bereits gibt, zuerst zum Lesen öffnen und die Position des Datensatzes suchen
if FileExists(DATEINAME) then begin
resetfile(datei_antworten, SizeOf(TAnworten));
while not EoF(datei_antworten) do begin
p := FilePos(datei_antworten);
Read(datei_antworten, antworten);
if (antworten.vname = vname) and (antworten.nname=nname) then
// Hier ist der Datensatz gefunden. "p" hat sich die Position in der Datei gemerkt.
break;
end;
closeFile(datei_antworten);
end else
p := 0;
// Nun die Datei ein 2. Mal zum schreiben öffnen und an Position "p" den neuen Datensatz schreiben
rewriteFile(datei_antworten, Sizeof(TAntworten));
Seek(datei_antworten, p);
antworten.vname := vname;
antworten.nname := nname;
// usw - die Felder des Record füllen...
Write(datei_antworten, antworten); // Hier wird der bisherige Record in der Datei überschreiben. Weil alle Records gleich groß sind, wird nichts zerstört!
closeFile(datei_antworten);
[EDIT] Ich habe schon seit Urzeiten nichts mehr mit klassischen Dateien gemacht... Bin nicht mehr sicher, ob nicht die Datei bei "rewrite" gelöscht wird. --> ausprobieren. Und es fehlt oben noch die Deklaration der Dateivariablen:
Generell würde ich das Programm nicht mit klassischen Dateien angehen. Schon eine einfache INI-Datei für Fragen und Ergebnisse würde manches einfacher und klarer machen:
Code: Alles auswählen
uses
IniFiles;
type
TFrage = record
Frage: String;
Antwort1: String;
Antwort2: String;
Antwort3: String;
Richtig: Integer;
end;
var
FragenArray: Array of TFrage;
procedure TForm3.B_starttestClick(Sender: TObject);
var
ini: TIniFile;
L: TStringList;
key: String;
begin
ini := TIniFile.Create('fragen.txt'); // Die Endung ".db" klingt zu sehr nach Datenbank
L := TStringList.Create;
try
ini.ReadSection('Fragen', L);
SetLength(FragenArray, L.Count);
for i:=0 to L.Count-1 do begin
key := 'Frage' + IntToStr(i+1);
Fragen[i].Frage := ini.ReadString(key, 'Frage', '');
Fragen[i].Antwort1 := ini.ReadString(key, 'Antwort1', '');
Fragen[i].Antwort2 := ini.ReadString(key, 'Antwort2', '');
Fragen[i].Antwort3 := ini.ReadString(key, 'Antwort3', '');
Fragen[i].Richtig := ini.ReadInteger(key, 'Richtig', -1);
end;
finally
L.Free;
ini.Free;
end;
RG_frage.Caption:=Fragen[0].Frage; //Füllen der Überschrift der RadioGroup mit der Frage Nr. 1 aus der Datei
RB_1.Caption:=Fragen[0].Antwort1; //Füllen des 1. Radiobuttons mit der Antwort Nr. 1 zur Frage 1 aus der Datei
RB_2.Caption:=Fragen[0].Antwort2; //Füllen des 2. Radiobuttons mit der Antwort Nr. 2 zur Frage 1 aus der Datei
RB_3.Caption:=Fragen[0].Antwort3; //Füllen des 3. Radiobuttons mit der Antwort Nr. 3 zur Frage 1 aus der Datei
B_pruefen.Visible:=true;
end;
Diese Ini-Datei ist eine Text-Datei, die du mit jedem Editor erstellen und ändern kannst - bei deinen eigenen Dateien geht das nicht. Hier wäre eine Beispiel:
Code: Alles auswählen
[Frage1]
Frage=How do you do?
Antwort1=Wie geht es Ihnen?
Antwort2=Wie alt sind Sie?
Antwort3=Was tun Sie da?
Richtig=1
[Frage2]
.... usw