Fragen Textdateien und Lazarus

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
echochrome
Beiträge: 11
Registriert: Sa 22. Jun 2013, 15:21

Fragen Textdateien und Lazarus

Beitrag von echochrome »

Hallöchen,
ich habe zwar gehofft drum herum zu kommen euch zu fragen, aber ich hab schon wieder ein Problem.

Ich will bei meinem Quiz eine Textdatei mit dem Namen des "Schülers/Spielers" als Name der Datei nehmen. Kein Problem.
Ich will dass in der ersten Zeile des Textfeldes "Dieser Test gehört xy xy.". Kein Problem.

Mein Problem beginnt jetzt.
Ich will nun nach jedem Prüfen der Antwort, sowohl die Frage, die Antwort und die Punktzahl speichern. Dabei aber die erste Zeile im Textfeld nicht löschen. Dass bekomme ich leider nicht hin.

Nächstes Problem besteht darin, dass 4 Fragen und Antworten so untereinander gespeichert werden sollen und am Ende die Gesamtpunktzahl.

Ganz vergessen, die Textdatei soll nach beenden der 4 Fragen, schreibgeschützt gemacht werden, dass es nicht mehr verfälscht werden kann.

Letztes Problem, die Antwort befindet sich in einem RadioButton, wie kann ich die Antwort aus dem RadioButton in die Textdatei speichern, bzw. wie kann ich auslesen welches der RadioButton aktiviert wurde und dies dann in die Textdatei schreiben.

Hier mal ein wenig Code an dem ich bastel:

Code: Alles auswählen

type
  TFrage = record
    quest: string[100];
    a1, a2, a3, a4: string[50];
    correct: integer;
  end;
 
type
  TErgebnisse = record
 
  end;
 
var
  Form8: TForm8;
  datei: file of TFrage;
  fragen: array[1..5] of TFrage;
  datensatz: TFrage;
  qnr, points, i,j: integer;
  t:TextFile;
  n,vn:string;
 
implementation
 
uses unit1;
 
{ TForm8 }
 
procedure TForm8.Button1Click(Sender: TObject);
begin
  if (Form8.Edit1.Text = '') and (Form8.Edit2.Text = '') then
    ShowMessage('Fehler! Erst den Namen und Vornamen eintragen.')
  else
  begin
    n:=Edit2.Text;
    vn:=Edit1.Text;
    //Versuch die .txt datei zu lesen um zu schreiben
    AssignFile(t, ''+n+'.'+vn+'.txt');
    ReWrite(t);
 
    //Testprozedur
    WriteLn(t,'Test von '+n+', '+vn+'.' );
 
    //Datei schließen
    CloseFile(t);
 
 
 
    Form8.Edit1.Enabled := False;
    Form8.Edit2.Enabled := False;
    Form8.Label2.Visible := True;
    Form8.Label3.Visible := True;
    Form8.RadioButton1.Visible := True;
    Form8.RadioButton2.Visible := True;
    Form8.RadioButton3.Visible := True;
    Form8.RadioButton4.Visible := True;
    Form8.BitBtn1.Visible := False;
    Form8.Button2.Visible := True;
    Form8.Image1.Visible := True;
    Form8.Panel2.Visible := True;
 
    qnr := 1;
    points := 0;
    assignfile(datei, 'informatik.db');
    reset(datei);
    i := 0;
    seek(datei, 0);
    while not EOF(datei) do
    begin
      seek(datei, i);
      Read(datei, datensatz);
      i := i + 1;
      fragen[i].quest := datensatz.quest;
      fragen[i].a1 := datensatz.a1;
      fragen[i].a2 := datensatz.a2;
      fragen[i].a3 := datensatz.a3;
      fragen[i].a4 := datensatz.a4;
      fragen[i].correct := datensatz.correct;
 
      Form8.Label3.Caption := fragen[1].quest;
      Form8.RadioButton1.Caption := fragen[1].a1;
      Form8.RadioButton2.Caption := fragen[1].a2;
      Form8.RadioButton3.Caption := fragen[1].a3;
      Form8.RadioButton4.Caption := fragen[1].a4;
    end;
  end;
end;
 
procedure TForm8.Button2Click(Sender: TObject);
 
var
  richtig: boolean;
 
begin
      //Versuch die .txt datei zu lesen um zu schreiben
    AssignFile(t, ''+n+'.'+vn+'.txt');
    ReWrite(t);
 
    //Testprozedur
    WriteLn(t,'');
    WriteLn(t,'Frage: '+fragen[qnr].quest );
    WriteLn(t,'Antwort: ');
    WriteLn(t,'Punkte: '+ inttostr(points));
 
    //Datei schließen
    CloseFile(t);
  Form8.Button2.Enabled := False;
  Form8.Button3.Visible := True;
  richtig := False;
 
  case fragen[qnr].correct of
    4: if Form8.RadioButton4.Checked then
        richtig := True;
    3: if Form8.RadioButton3.Checked then
        richtig := True;
    2: if Form8.RadioButton2.Checked then
        richtig := True;
    1: if Form8.RadioButton1.Checked then
        richtig := True;
  end;
 
  if richtig = True then
  begin
    points := points + 1;
    Form8.Panel2.Visible := True;
    Form8.Panel2.font.color := clLime;
    Form8.Panel2.Caption := 'RICHTIG!';
  end
  else
  begin
    Form8.Panel2.Visible := True;
    Form8.Panel2.Caption := 'FALSCH!';
    Form8.Panel2.font.color := clRed;
  end;
 
  if qnr = 4 then
  begin
    Form8.Button4.Visible := True;
    Form8.BitBtn1.Visible := True;
    Form8.Button3.Visible := False;
  end;
 
  Form8.RadioButton1.Enabled := False;
  Form8.RadioButton2.Enabled := False;
  Form8.RadioButton3.Enabled := False;
  Form8.RadioButton4.Enabled := False;
 
end;
 
procedure TForm8.Button3Click(Sender: TObject);
begin
  Form8.Button2.Enabled := True;
  Form8.Button3.Visible := False;
  Form8.Panel2.Visible := False;
  qnr := qnr + 1;
  Form8.Label3.Caption := fragen[qnr].quest;
  Form8.RadioButton1.Caption := fragen[qnr].a1;
  Form8.RadioButton2.Caption := fragen[qnr].a2;
  Form8.RadioButton3.Caption := fragen[qnr].a3;
  Form8.RadioButton4.Caption := fragen[qnr].a4;
 
  Form8.Image1.Visible := False;
  Form8.RadioButton1.Checked := False;
  Form8.RadioButton2.Checked := False;
  Form8.RadioButton3.Checked := False;
  Form8.RadioButton4.Checked := False;
  Form8.RadioButton1.Enabled := True;
  Form8.RadioButton2.Enabled := True;
  Form8.RadioButton3.Enabled := True;
  Form8.RadioButton4.Enabled := True;
  end;
 
Sorry ist ein wenig viel, ich weiß, weiß nur nicht was ihr braucht um dahinter zu steigen :)

Ich hoffe Ihr könnt mir dabei helfen

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Fragen Textdateien und Lazarus

Beitrag von Michl »

Muss es unbedingt eine Textdatei sein?!

Gerade
echochrome hat geschrieben:Ganz vergessen, die Textdatei soll nach beenden der 4 Fragen, schreibgeschützt gemacht werden, dass es nicht mehr verfälscht werden kann.
ist bei einer Textdatei besonders einfach zu umgehen, selbst wenn man Dateiattribute "nur lesen" setzt, kann man diese mittels einen einfachen Editors ändern.

Ich würde für soetwas eine typisierte Datei nehmen!

Ansonsten wäre Delimitedtext noch interessant.

Eine Möglichkeit wäre evtl. auch alle Daten nacheinander in eine Stringlist zu schreiben und diese dann einfach zu speichern (So, wie man die Strings der Stringlist zufügt, einfach wieder auseinander nehmen).

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

echochrome
Beiträge: 11
Registriert: Sa 22. Jun 2013, 15:21

Re: Fragen Textdateien und Lazarus

Beitrag von echochrome »

Leider ist eine Textdatei ausschließlich gewünscht.

wie meinst du dass mit der Stringlist??

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Fragen Textdateien und Lazarus

Beitrag von Michl »

echochrome hat geschrieben:Leider ist eine Textdatei ausschließlich gewünscht.
Schade, find ich nicht die beste Lösung. Wenn es aber eine Übung sein soll, dann versteh ich das!

Muss keine Stringlist sein, man kann auch die Strings einfach nacheinander in eine Textdatei schreiben. Man muss nur die Reihgenfolge und die Länge der Zeichen definieren. Vorteil der Stringlist wäre nur, dass man sich diese in einem Memo so direkt anzeigen lassen kann.

[edit]
Du kannst auch in jeder Zeile eine Variable speichern und diese genauso wieder auslesen mit writeln(Datei, ...) und readln(Datei, ...)!
Zuletzt geändert von Michl am Sa 20. Jul 2013, 23:11, insgesamt 2-mal geändert.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

echochrome
Beiträge: 11
Registriert: Sa 22. Jun 2013, 15:21

Re: Fragen Textdateien und Lazarus

Beitrag von echochrome »

sieht der Text in der Textdatei dann etwa so aus?


Frage: Das Feld wurde mit Bubblesort sortiert. In welcher Zeile ist der Fehler?
Antwort: (fehlt leider noch)
Punkte: 1

Frage: nächste Frage
Antwort: (fehlt leider noch)
Punkte: 1

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Fragen Textdateien und Lazarus

Beitrag von Michl »

Wenn du das so haben willst, dann nimm Writeln(Datei, ...).

... und ja, wenn du dir merkst, wie du die Daten in die Datei geschrieben hast, dann kannst du sie auch genau so wieder auslesen...
echochrome hat geschrieben:Letztes Problem, die Antwort befindet sich in einem RadioButton, wie kann ich die Antwort aus dem RadioButton in die Textdatei speichern, bzw. wie kann ich auslesen welches der RadioButton aktiviert wurde und dies dann in die Textdatei schreiben.
z.B:

Code: Alles auswählen

  if RadioButton1.Checked then WriteLn(Datei,'Gewählt wurde Radiobutton1');
  if RadioButton2.Checked then WriteLn(Datei,'Gewählt wurde Radiobutton2');

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Fragen Textdateien und Lazarus

Beitrag von Michl »

Habe mir gerade nochmal dein erstes Posting durchgelesen. Ich glaube, ich habe deine Zielsetzung fehlgedeutet. Du willst bestimmt nur eine Textdatei haben, die man ansehen bzw. ausdrucken kann. Dir geht es nicht darum, den Test (die Daten vom Test) wieder einzulesen.

Da du zu jeder Zeit eine Textdatei erstellt haben möchtest und nicht erst, wenn alle Fragen beantwortet sind, so musst du sowieso immer alle Daten neu schreiben.

Dann wäre es wirklich das einfachste, du generierst dir eine Stringlist (z.B. bei OnCreate deiner Form) mit ... Zeilen (Strings). Die erste Zeile ist für den Namen, die dritte Zeile für die 1.Frage, die vierte für die 1.Antwort usw. reserviert. Immer, wenn du eine Eingabe gemacht hast, kannst du diese Stringlist updaten.

Also brauchst du immer nur die entsprechende Zeile deiner Stringlist zu ändern. Wenn z.B. Frage 3 in Zeile 15 (Index 14) steht und gerade beantwortet wurde, dann brauchst du nur:

Code: Alles auswählen

Stringlist.Strings[14]:=Frage;
Stringlist.Strings[15]:=Antwort;
Stringlist.Strings[16]:=inttostr(Punkte);
Damit entfällt das Wiedereinlesen der Textdatei.

Das Speichern der Stringlist geht dann quasi von selbst:

Code: Alles auswählen

Stringlist.SaveToFile('Datei.txt'); 
Aufruf nach jedem Update deiner Stringlist.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Bauer321
Beiträge: 465
Registriert: Sa 21. Aug 2010, 21:30
OS, Lazarus, FPC: Windows 7 Ultimate (L 1.2.2 FPC 2.6.4 32-bit)
CPU-Target: 64-Bit
Wohnort: nahe Bremen
Kontaktdaten:

Re: Fragen Textdateien und Lazarus

Beitrag von Bauer321 »

Das mit dem ändern könntest du über einen hash erschweren.
Du überlegst dir eine reihenfolge der fragen, machst daraus einen string von diesem lässt du dir den md5 hash errechnen, welchen du anschließend der datei hinzufügst. Kommt beim einlesen anschließendem erstellen des strings und der berechnung dessen hashs ein anderer wert raus verweigerst du das laden

Ist manipulierbar, schützt aber vor schnellen Änderungen durch unerfahrene nutzer
www.mcpatcher.net | www.hoeper.me

echochrome
Beiträge: 11
Registriert: Sa 22. Jun 2013, 15:21

Re: Fragen Textdateien und Lazarus

Beitrag von echochrome »

Ich habe jetzt versucht eine StringList zu erstellen. Dies sieht so aus:

Code: Alles auswählen

 
   var
   StringList: TStrings;
 
  form.create
 StringList:=TStringList.create
 
   procedure TForm8.Button2Click(Sender: TObject);  
   (...)
    StringList.Strings[1]:='Test von '+n+', '+vn+'.';
    StringList.Strings[3]:='Frage: '+fragen[1].quest;
    StringList.Strings[4]:='Antwort: '+ tea1;
    StringList.Strings[5]:='Punkte: '+ inttostr(points);
 
    StringList.Strings[7]:='Frage: '+fragen[2].quest;
    StringList.Strings[8]:='Antwort: '+ tea2;
    StringList.Strings[9]:='Punkte: '+ inttostr(points);
 
    StringList.Strings[11]:='Frage: '+fragen[3].quest;
    StringList.Strings[12]:='Antwort: '+ tea3;
    StringList.Strings[13]:='Punkte: '+ inttostr(points);
 
    StringList.Strings[15]:='Frage: '+fragen[4].quest;
    StringList.Strings[16]:='Antwort: '+ tea4;
    StringList.Strings[17]:='Punkte: '+ inttostr(points);
 
 
 procedure TForm8.Button4Click(Sender: TObject);
 (...)
    StringList.SaveToFile(''+n+'.'+vn+'.txt'); 
 

Allerdings bekomme ich immer die Fehlermeldung "Projekt project1 hat Exception-Klasse >>External SIGSEGV<< ausgelöst.
In Datei 'unit8.pas' in Zeile 224: StringList.Strings[1]:='Test von '+n+','+vn+'.';
Das Problem habe ich doch gelöst bekommen, aber jetzt ist ein neuer aufgetreten:

Projekt project1 hat Exception-Klasse >>EStringListError<< ausgelöst mit der Meldung: List index (1) out of bounds

Bei Adresse 444128


Damit kann ich leider nichts anfangen...

Habt ihr eine Ahnung was da schief läuft?

Benutzeravatar
theo
Beiträge: 10873
Registriert: Mo 11. Sep 2006, 19:01

Re: Fragen Textdateien und Lazarus

Beitrag von theo »

Du musst StringList.Add('abc'); verwenden

http://www.delphibasics.co.uk/RTL.asp?Name=TStringList

creed steiger
Beiträge: 958
Registriert: Mo 11. Sep 2006, 22:56

Re: Fragen Textdateien und Lazarus

Beitrag von creed steiger »


echochrome
Beiträge: 11
Registriert: Sa 22. Jun 2013, 15:21

Re: Fragen Textdateien und Lazarus

Beitrag von echochrome »

Ich habe eure Tipps jetzt durchgelesen bzw. berücksichtigt.

ABER... wenn ich es mit StringList.Add anfüge, bricht dass Programm nach der ersten Frage ab.. Leider schade und ich weiß nicht woran es noch liegen könnte...

ich dachte ich müsse dass mit den [] angeben dass ich alles untereinander schreiben kann.

Habt ihr eine Idee die vielleicht fruchten könnte??
Muss ich für 4 Fragen 4 verschiedene Button machen, sodass ich pro Button nur eine Frage, eine Antwort und einmal Punkte speichere.

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Fragen Textdateien und Lazarus

Beitrag von Michl »

echochrome hat geschrieben:

Code: Alles auswählen

 form.create  //??????????????????????? was bezweckst du hier?
 StringList:=TStringList.create  //prinzipiel richtig, würde ich aber nach OnCreate deiner Form verschieben
 z.B:

Code: Alles auswählen

procedure TForm8.FormCreate(Sender: TObject);
var
  i:integer;
begin
  StringList:=TStringList.create;
 
//so 
  for i:=0 to 18 do StringList.Add(''); //Hier noch die Strings (Platz im Speicher dafür reservieren) erstellen !!!!!!!!!
 
//oder so: Ich würde hier jedoch gleich die Strings erstellen, die zu Laufzeit dann nur noch "geupdatet" werden:
  StringList.add('Test von Mustermann, Max');
  StringList.add('');
  StringList.add('Frage: Noch nicht bekannt');
  StringList.add('Antwort: noch keine');
  StringList.add('Punkte: 0');
  ...  
end; 
jetzt sollte auch deine Zuweisung funktionieren:
echochrome hat geschrieben:

Code: Alles auswählen

   procedure TForm8.Button2Click(Sender: TObject);  
   (...)
    StringList.Strings[1]:='Test von '+n+', '+vn+'.';
    StringList.Strings[3]:='Frage: '+fragen[1].quest;
    StringList.Strings[4]:='Antwort: '+ tea1;
    StringList.Strings[5]:='Punkte: '+ inttostr(points);
 
    StringList.Strings[7]:='Frage: '+fragen[2].quest;
    StringList.Strings[8]:='Antwort: '+ tea2;
    StringList.Strings[9]:='Punkte: '+ inttostr(points);
 
    StringList.Strings[11]:='Frage: '+fragen[3].quest;
    StringList.Strings[12]:='Antwort: '+ tea3;
    StringList.Strings[13]:='Punkte: '+ inttostr(points);
 
    StringList.Strings[15]:='Frage: '+fragen[4].quest;
    StringList.Strings[16]:='Antwort: '+ tea4;
    StringList.Strings[17]:='Punkte: '+ inttostr(points);
oder so:

Code: Alles auswählen

   procedure TForm8.Button2Click(Sender: TObject);  
   (...)
    Stringlist.Clear;
    StringList.add('');
    StringList.add('Test von '+n+', '+vn+'. ');
    StringList.add('');
    StringList.add('Frage: '+fragen[1].quest);
    StringList.add('Antwort: '+ tea1);
    StringList.add('Punkte: '+ inttostr(points));
.... 
Müsstest dann aber bei jedem Fragendurchgang die vorherigen Fragen/Anworten etc. zwischenspeichern (z.B. in einem Record) ...
Zuletzt geändert von Michl am So 21. Jul 2013, 22:22, insgesamt 1-mal geändert.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

echochrome
Beiträge: 11
Registriert: Sa 22. Jun 2013, 15:21

Re: Fragen Textdateien und Lazarus

Beitrag von echochrome »

super! ich habe es scheinbar übersehen, dass man der StringListe die größe schon sagen muss.
jetzt funktioniert es.

Tausend Dank für eure Hilfe!

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Fragen Textdateien und Lazarus

Beitrag von Michl »

echochrome hat geschrieben:super! ich habe es scheinbar übersehen, dass man der StringListe die größe schon sagen muss.
Das ist so nicht richtig. Du hast zuvor nur einen Zugriff auf einen noch nicht erstellten String gemacht.

Mit Stringlist.add fügst du einen String hinzu, wenn du 10 Strings hinzugefügt (mit add) hast, kannst du dann auf die einzelnen Strings[0..9] zugreifen!

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Antworten