Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Aus gegebenem Anlass poste ich hier mal ein allgemeines „Gerüst“ das zeigt, wie sich Textdateien miteinander verschmelzen lassen.
Nach dem Lesen der Variablen 'line1$' und 'line2$' kann deren Inhalt selbstverständlich geändert werden, bevor er in die Ausgabe-Datei geschrieben wird.
; -- erfolgreich getestet mit PB 6.00
EnableExplicit
Procedure.i MergeTextFiles (inFile1$, inFile2$, outFile$)
; -- Zwei Textdateien zu einer neuen verschmelzen, indem aus
; beiden Dateien abwechselnd je eine Zeile genommen wird.
; in : inFile1$, inFile2$: Namen der beiden Eingabe-Dateien;
; Format UTF-8 mit oder ohne BOM.
; outFile$ : Name der zu erzeugenden Ausgabe-Datei;
; Sie wird das Format UTF-8 ohne BOM haben.
; out: Funktionswert: 0 bei Fehler, 1 bei Erfolg
Protected.i ifn1, ifn2, remaining, ofn, fmt
Protected line1$, line2$
; -- Alle beteiligten Dateien öffnen und Eingabe-Formate prüfen.
ifn1 = ReadFile(#PB_Any, inFile1$)
If ifn1 = 0
ProcedureReturn 0
EndIf
fmt = ReadStringFormat(ifn1)
If fmt <> #PB_Ascii And fmt <> #PB_UTF8
CloseFile(ifn1)
ProcedureReturn 0
EndIf
ifn2 = ReadFile(#PB_Any, inFile2$)
If ifn2 = 0
CloseFile(ifn1)
ProcedureReturn 0
EndIf
fmt = ReadStringFormat(ifn2)
If fmt <> #PB_Ascii And fmt <> #PB_UTF8
CloseFile(ifn1)
CloseFile(ifn2)
ProcedureReturn 0
EndIf
ofn = CreateFile(#PB_Any, outFile$)
If ofn = 0
CloseFile(ifn1)
CloseFile(ifn2)
ProcedureReturn 0
EndIf
; -- Schleife, solange beide Eingabe-Dateien noch nicht zu Ende gelesen sind.
remaining = 0
Repeat
If Eof(ifn1)
remaining = ifn2
Break
ElseIf Eof(ifn2)
remaining = ifn1
Break
Else
line1$ = ReadString(ifn1)
line2$ = ReadString(ifn2)
WriteStringN(ofn, line1$)
WriteStringN(ofn, line2$)
EndIf
ForEver
; -- Eine Eingabe-Datei ist zu Ende gelesen.
; Falls in der anderen noch Zeilen übrig sind, auch diese in die Ausgabe-Datei schreiben.
If remaining = ifn1
While Eof(ifn1) = #False
line1$ = ReadString(ifn1)
WriteStringN(ofn, line1$)
Wend
ElseIf remaining = ifn2
While Eof(ifn2) = #False
line2$ = ReadString(ifn2)
WriteStringN(ofn, line2$)
Wend
EndIf
; -- Alle beteiligten Dateien schließen und Code für Erfolg zurückgeben.
CloseFile(ifn1)
CloseFile(ifn2)
CloseFile(ofn)
ProcedureReturn 1
EndProcedure
; -- Demo
Define path$, inFile1$, inFile2$, outFile$
path$ = "C:\Users\Nino\Desktop\"
inFile1$ = path$ + "Liste1.txt"
inFile2$ = path$ + "Liste2.txt"
outFile$ = path$ + "Liste_gesamt.txt"
If MergeTextFiles(inFile1$, inFile2$, outFile$)
Debug "Erfolg, s. Datei '" + outFile$ + "'"
Else
Debug "Fehler"
EndIf
Zuletzt geändert von Nino am 26.10.2022 23:41, insgesamt 1-mal geändert.
EnableExplicit
Procedure.i MergeTextFiles (Array infile$(1), outFile$)
; -- Beliebig viele Textdateien zeilenweise zu einer neuen verschmelzen.
; in : infile$(1) : Dateinamen der Eingabe-Dateien;
; Format UTF-16, UTF-8, ASCII mit oder ohne BOM.
; outFile$ : Name der zu erzeugenden Ausgabe-Datei;
; Sie wird das Format UTF-8 ohne BOM haben.
; out: Funktionswert: 0 bei Fehler, 1 bei Erfolg
Protected num_files= ArraySize(infile$())+1
Protected Dim file_handle.i(num_files)
Protected Dim file_format.i(num_files)
Protected ofn
Protected a,b, open_files
; -- Alle beteiligten Dateien öffnen und Eingabe-Formate prüfen und speichern.
For a=0 To num_files-1
file_handle(a) = ReadFile(#PB_Any, infile$(a))
If file_handle(a) = 0
For b = 0 To a-1
CloseFile(file_handle(b))
Next
ProcedureReturn 0
EndIf
file_format(a) = ReadStringFormat(file_handle(a))
If file_format(a) <> #PB_Ascii And file_format(a) <> #PB_UTF8 And file_format(a) <> #PB_Unicode
; Auch alle vorherigen Dateien müssen aufgeräumt werden
For b=0 To a
CloseFile(file_handle(b))
Next
ProcedureReturn 0
EndIf
Next
; Ausgabedatei erstellen
ofn = CreateFile(#PB_Any, outFile$)
If ofn = 0
For a=0 To num_files-1
CloseFile(file_handle(b))
Next
ProcedureReturn 0
EndIf
; -- Schleife, solange Eingabe-Dateien noch nicht zu Ende gelesen sind.
open_files = num_files
Repeat
For a=0 To num_files-1
If file_handle(a)
; Am Ande der Datei schließen wir sie und setzen den Handle auf 0, damit sie später ignoriert wird.
If Eof(file_handle(a))
open_files - 1
CloseFile(file_handle(a))
file_handle(a) = 0
Else
; Sonst lesen wir eine Zeile im gespeicherten Format und schreiben sie
WriteStringN( ofn , ReadString(file_handle(a), file_format(a) ) )
EndIf
EndIf
Next
Until open_files = 0
; -- Alle beteiligten Dateien schließen und Code für Erfolg zurückgeben.
CloseFile(ofn)
ProcedureReturn 1
EndProcedure
; -- Demo
Define path$, inFile1$, inFile2$, outFile$
path$="X:\"
Dim Infile$(1)
Infile$(0) = path$ + "Liste1.txt"
Infile$(1) = path$ + "Liste2.txt"
outFile$ = path$ + "Liste_gesamt.txt"
If MergeTextFiles(Infile$(), outFile$)
Debug "Erfolg, s. Datei '" + outFile$ + "'"
Else
Debug "Fehler"
EndIf
Unterschiede:
Man kann nun beliebig viele Dateien zusammenfügen.
Der Code kann auch mit UTF-16 umgehen indem er sich das Format merkt
Und es ist sogar etwas kürzer
Edit: Noch den Schnipsel in der Antwort ergänzt
Zuletzt geändert von Macros am 26.10.2022 19:56, insgesamt 1-mal geändert.
For a=0 To num_files-1
file_handle(a) = ReadFile(#PB_Any, infile$(a))
If file_handle(a) = 0
ProcedureReturn 0
EndIf
[...]
Es fehlt eine Schleife, welche bei einem Fehler beim Öffnen einer Datei die bis dahin geöffneten Dateien wieder schließt (ähnlich wie sie an anderer Stelle deines Codes vorkommt).
D.h. ich würde diese Stelle so schreiben:
For a = 0 To num_files-1
file_handle(a) = ReadFile(#PB_Any, infile$(a))
If file_handle(a) = 0
For b = 0 To a-1
CloseFile(file_handle(b))
Next
ProcedureReturn 0
EndIf
[...]