Seite 1 von 2

Dateien einlesen und damit arbeiten

Verfasst: 26.12.2007 01:01
von PB42
Hallo,

ich will aus einer Datei Zahlen einlesen und dann damit im Programm arbeiten (z.B. als erste Übung Doubletten herausfinden). Die PB-Hilfe nutzt mir absolut nichts. Kann mir mal bitte jemand einen kurzen Musterquellcode schreiben, wie man sowas macht? Vielen Dank.

PB42

edit.: Eilt nicht, ist ja schon spät. Morgen ist auch noch ein Tag.

Verfasst: 26.12.2007 01:15
von STARGÅTE
Wenn deine Zahlen als LONGs in der Datei vorliegen dann so:

Code: Alles auswählen

ReadFile(1, Datei$)
 Zahl1 = ReadLong(1)
 Zahl2 = ReadLong(1)
 ;...
CloseFile(1)
Wenn deine Zahlen als Text vorliegen, getrennt mit einem "Trannungszeichen" (",",".","_",...) dann so:

Code: Alles auswählen

ReadFile(1, Datei$)
 String$ = ReadString(1)
 Zahl1 = StringField(String$, 1, Trennzeichen$)
 Zahl2 = StringField(String$, 2, Trennzeichen$)
 ;...
CloseFile(1)

Verfasst: 26.12.2007 01:17
von AND51
Ich nehme an, du willst als Übung z. B. 100 Zufallszahlen in eine Datei schreiben, pro zeile eine Zahl? Diese Datei dann wieder auslesen und die doppelten Zahlen filtern?

Das ist ganz einfach! So erstellst du die Datei:

Code: Alles auswählen

If Not CreateFile(0, "C:\test.txt")
   Debug "Datei kann nicht erstellt werden"
   End
EndIf

For n=1 to 100
   WriteStringN(0, Str(Random(10)))
Next

CloseFile(0)
Diesen Code habe ich aus dem Kopf geschrieben, sollte funktionieren!

So liest du die Zahlen ein (ich lese die Zahlen in eine LinkedList ein):

Code: Alles auswählen

If Not ReadFile(0, "C:\test.txt")
   Debug "Datei kann nicht gelesen werden"
   End
EndIf

NewList zahlen.l()

While Not Eof(0)
   AddElement(zahlen())
      zahlen()=Val(ReadString(0))
Wend

CloseFile(0)

; Ab hier werden Dubletten gefiltert
; Beste und schnellste Methode: Jedes Element mit allen nachfolgenden Elementen vergleichen!

Debug "Die Liste hat vorher "+Str(CountList(zahlen()))+" Elemente"

For element=0 to CountList(zahlen())-1
   SelectElement(zahlen(), element) ; Ein Element wählen
   Define element_inhalt=zahlen() ; Dieses Element merken
   While NextElement(zahlen()) ; Alle nachfolgenden Elemente durchgehen
      If zahlen() = element_inhalt ; Wenn das eben gemerkte Element gleich dem aktuellen Element ist, dann löschen
         DeleteElement(zahlen())
      EndIf
   Wend
Next

Debug "Nach der Filterung hat die Liste noch "+Str(CountList(zahlen()))+" Elemente"
Auch diesen Code habe ich mal eben aus dem Kopf getippt.
// Edit: Mal eben 3 Dusseligkeitsfehler korrigiert (EndIf vergessen und so) :-)

Ich persönlich bevorzuge diese Methode der Dublettenfilterung.
Natürlich kann man auch, wie einige andere es tun, die Liste sortieren (SortList()), dann stehen alle Dubletten hintereinander. Meine Methode kommt jedoch ohne Sortierung aus; das ist notwendig, denn es kann ja oft Situationen geben, in der die Reihenfolge der Elemente z. B. durch Sortieren nicht verloren gehen darf.

Verfasst: 26.12.2007 01:31
von PB42
Ich hab mir das alles erstmal abgespeichert und mache dann morgen damit meine ersten Gehübungen. Wenn ich nicht klarkommen sollte, melde ich mich halt nochmal.

Danke erstmal.

PB42

Verfasst: 26.12.2007 12:25
von Bisonte
@STARGÅTE:

Aber selbst bei 3.3 würd das nen Fehler produzieren ...

Da musst du bei deinem 2. Beispiel noch ein VAL() benutzen... ist doch'n String...

Code: Alles auswählen

Zahl2 = Val( StringField(String$, 2, Trennzeichen$)) 
Frohe Weihnachten ;)

Verfasst: 26.12.2007 13:59
von STARGÅTE
ja klar lol, aber ich teste halt kleine codes nicht :oops:

Verfasst: 27.12.2007 00:58
von PB42
Hallo,

ich habe mich heute stundenlang mit dem Einlesen einer kleinen Datai beschäftigt, aber der Code, der dabei entstanden ist, um mit den eingelesenen Zahlen in Form von Variablen auch arbeiten zu können, statt die Zahlen nur im Debugger ansehen zu können, ist so schlimm, daß ich den hier nicht einstellen will. Es muß doch einen effizienten Weg geben, mit dem man z.B. die Zahlenreihen

1, 12, 15, 24
13, 61, 39, 43

nacheinander in Variablen abspeichern und bearbeiten kann, z.B., um mal übungshalber in der ersten Reihe Vielache von 12 zu finden und in der zweiten dann Vielfache von 13. Es gibt aber in PureBasic nicht sowas wie EndOfRow(). Falls da jemand weiter weiß, wäre ich dankbar.

PB42

Verfasst: 27.12.2007 01:11
von STARGÅTE
also deine Datei ist also das hier :
MeineDatei.txt hat geschrieben: 1, 12, 15, 24
13, 61, 39, 43
gut dann ist hier dein gewünschter Code:

Code: Alles auswählen

If ReadFile(1, "MeineDatei.txt")
 Repeat
  Zeile$ = ReadString(1)
  Index = 1
  While StringField(Zeile$,Index,", ") <> ""
   Zahl = Val(Trim(StringField(Zeile$,Index,",")))
   If Zahl % 13 = 0
    Debug Str(Zahl)+" ist duch 13 teilbar."
   EndIf
   If Zahl % 12 = 0
    Debug Str(Zahl)+" ist duch 12 teilbar."
   EndIf
   Index + 1
  Wend
 Until Eof(1)
 CloseFile(1)
EndIf
Ergebnis:
12 ist duch 12 teilbar.
24 ist duch 12 teilbar.
13 ist duch 13 teilbar.
39 ist duch 13 teilbar.

Verfasst: 27.12.2007 01:28
von Kiffi
STARGÅTE hat geschrieben:

Code: Alles auswählen

[...]
StringField(Zeile$,Index,", ")
1. Das Trennzeichen in StringField sollte korrekterweise mit nur einem
Zeichen angegeben werden.

2. Es sollte immer geprüft werden, ob Dateioperationen funktioniert haben:

Code: Alles auswählen

If ReadFile(1, "MeineDatei.txt") 
 [...]
Grüße ... Kiffi

Verfasst: 27.12.2007 01:36
von PB42
@STARGATE

Ist ja phänomenal, das klappt echt super! Das ist alleridngs ein Code, wo ich jetzt nicht kappiere, warum der läuft, denn das mit den %-Zeichen habe ich noch nie gesehen. Kriege ich vielleicht noch raus. Vielen Dank!

@Kiffi
Auch natürlich Danke.

Ich ziehe echt den Hut vor Leuten, die so schnell helfen können Dank ihres Programmierkönnens.

PB42