Sortierprogramm fast fertig. Noch ein Fehler...

Anfängerfragen zum Programmieren mit PureBasic.
SebastianJu2
Beiträge: 180
Registriert: 24.09.2010 10:39

Sortierprogramm fast fertig. Noch ein Fehler...

Beitrag von SebastianJu2 »

Das Sortierprogramm ist fast fertig nur gibt es noch einen Fehler. NoCase wird nicht beachtet.

Hier mal der ganze Code:

Code: Alles auswählen

Procedure Msg(Msg$,Type.l = 0) ;If Type isnt set the Message is a Errormessage
  If Type = 0 : Type$ = "Error" : Else : Type$ = "Message" : EndIf
  MessageRequester(Type$, Type$+": " + Msg$, 0)
  If Type = 0 : End : EndIf
EndProcedure

Procedure ChkCreated(Handle,Type$)
  If Handle = 0 : Msg("Couldnt create " + Type$) : EndIf
EndProcedure

MainWindowHandle=OpenWindow(#PB_Any, 0, 0, 600, 140, "SortIt", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_ScreenCentered)
ChkCreated(MainWindowHandle,"Window")

SourceButtonHandle = ButtonGadget(#PB_Any, 10, 10, 110, 25, "Choose Sourcefile")
ChkCreated(SourceButtonHandle,"Button")

TargetButtonHandle = ButtonGadget(#PB_Any, 10, 45, 110, 25, "Choose Targetfile")
ChkCreated(TargetButtonHandle,"Button")

SourceStringHandle = StringGadget(#PB_Any, 140, 10, 445, 25, "")
ChkCreated(SourceStringHandle,"Inputbox")

TargetStringHandle = StringGadget(#PB_Any, 140, 45, 445, 25, "")
ChkCreated(TargetStringHandle,"Inputbox")

SortAscOptionHandle = OptionGadget(#PB_Any, 140, 80, 100, 20, "Sort Ascending")
ChkCreated(SortAscOptionHandle,"Option")

SortDescOptionHandle = OptionGadget(#PB_Any, 140, 100, 100, 20, "Sort Descending")
ChkCreated(SortDescOptionHandle,"Option")

SetGadgetState(SortAscOptionHandle, 1)

SortNoCaseCheckboxHandle = CheckBoxGadget(#PB_Any, 260, 80, 120, 20, "Sort NoCase")
ChkCreated(SortNoCaseCheckboxHandle,"Checkbox")

DeleteBlankRowsCheckboxHandle = CheckBoxGadget(#PB_Any, 260, 100, 120, 20, "Delete Blank Rows")
ChkCreated(DeleteBlankRowsCheckboxHandle,"Checkbox")

StartButtonHandle = ButtonGadget(#PB_Any, 505, 80, 80, 50, "START")
ChkCreated(StartButtonHandle,"Button")

Repeat
  EventID = WaitWindowEvent()
  If EventWindow() = MainWindowHandle And EventID = #PB_Event_Gadget
    If EventGadget() = SourceButtonHandle
      File$ = OpenFileRequester("Please choose the file to read from", "", "Text (*.txt)|*.txt;*.bat|All Files (*.*)|*.*", 0)
      If File$
        If FileSize(File$) = -2 : Msg("A directory cant be the source",1) : File$ = "" : EndIf
        SetGadgetText(SourceStringHandle,File$)
      EndIf
    EndIf
    If EventGadget() = TargetButtonHandle
      File$ = OpenFileRequester("Please choose the file to write to", "", "Text (*.txt)|*.txt;*.bat|All Files (*.*)|*.*", 0)
      If File$
        If FileSize(File$) = -2 : Msg("A directory cant be the target",1) : File$ = "" : EndIf
        SetGadgetText(TargetStringHandle,File$)
      EndIf
    EndIf
    If EventGadget() = StartButtonHandle
      ;Stringgadgets unbeschreibbar für User machen?
      Repeat  
        If FileSize(GetGadgetText(SourceStringHandle)) = -1 : Msg("Sourcefile doesnt exist",1) : SetGadgetText(SourceStringHandle,"") : Break : EndIf
        If FileSize(GetGadgetText(SourceStringHandle)) = -2 : Msg("Sourcefile cant be a directory",1) : SetGadgetText(SourceStringHandle,"") : Break : EndIf
        If FileSize(GetGadgetText(TargetStringHandle)) = -2 : Msg("Targetfile cant be a directory",1) : SetGadgetText(TargetStringHandle,"") : Break : EndIf
        If FileSize(GetGadgetText(TargetStringHandle)) >= 0
          Result.l = MessageRequester("Request", "Targetfile already exists. Overwrite?", #PB_MessageRequester_YesNo)
          If Result = #PB_MessageRequester_No : Break : EndIf
        EndIf
        
        ReadFileHandle = ReadFile(#PB_Any, GetGadgetText(SourceStringHandle))
        WriteFileHandle = CreateFile(#PB_Any, GetGadgetText(TargetStringHandle))
        If Not ReadFileHandle : Msg("Couldnt open Sourcefile") : Break : EndIf
        If Not WriteFileHandle : Msg("Couldnt open Targetfile") : Break : EndIf
        
        Dim SourceFileContent$(0)
        x.l=0
        While Eof(ReadFileHandle) = 0
          ReDim SourceFileContent$(x)
          SourceFileContent$(x) = ReadString(ReadFileHandle);Ascii, UF8 usw beachten? Was ist mit ReadStringFormat?
          x+1
        Wend
        CloseFile(ReadFileHandle)
        
        Flags.l = 0 : DelBlank.l = 0
        If GetGadgetState(SortDescOptionHandle) = 1 : Flags+1 : EndIf
        If GetGadgetState(SortNoCaseCheckboxHandle) = 1 : Flags+2 : EndIf
        If GetGadgetState(DeleteBlankRowsCheckboxHandle) = 1 : DelBlank = 1 : EndIf
        SortArray(SourceFileContent$(), Flags)
        
        For x = 0 To ArraySize(SourceFileContent$())
          If DelBlank = 1 And SourceFileContent$(x) = "" : Continue : EndIf
          WriteStringN(WriteFileHandle, SourceFileContent$(x)) ;Ascii, UF8 usw beachten?
        Next
        CloseFile(WriteFileHandle)
        
        MessageRequester("Info","Success")
      Until #True
    EndIf
  EndIf
Until EventID = #PB_Event_CloseWindow
Es geht um SortArray(). Die Funktion hat die Möglichkeit per Parameter NoCase zu sortieren. Macht sie aber nicht. Ich habe in dem Array alle Zeilen aus einer Datei gespeichert. Unter anderem die Werte "a" und "A" und "sdf" und "SDF". Normalerweise sollten nur noch je ein Element vorhanden sein danach.
Auch wenn ich die Variable Flags rausnehme und nur die Konstante für NoCase einsetze funktioniert es nicht. Wie kommt das?

Ich dachte man könnte die Geschwindigkeit noch erhöhen indem man zB redim immer nur alle 1000 Zeilen für weitere 1000 Arraybestandteile macht und am Ende die überschüssigen mit redim abschneidet. Allerdings ist es selbst beim Sortieren von 213.142 Zeilen in unter einer Sekunde fertig. Aber schneller ist immer gut... :)

Dann habe ich mich gefragt ob man StringGadgets nach erstellen noch schreibgeschützt stellen kann. Dazu habe ich in der Hilfe nichts gefunden.

Und ich frage mich ob ich nicht auf ascii, utf8 usw Wert legen sollte. Bzw ReadStringFormat und sein BOM. Müsste man ja eigentlich um korrekt zu sortieren oder?

Und ansonsten? Gibts Verbesserungsvorschläge? :)
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Sortierprogramm fast fertig. Noch ein Fehler...

Beitrag von NicTheQuick »

SebastianJu2 hat geschrieben:Dann habe ich mich gefragt ob man StringGadgets nach erstellen noch schreibgeschützt stellen kann. Dazu habe ich in der Hilfe nichts gefunden.
Ja, das geht, aber ich weiß nicht auswendig wie. Das ist vor allem unter Windows und Linux unterschiedlich. Die Forum-Suche oder Google sollten allerdings weiterhelfen.
Und ich frage mich ob ich nicht auf ascii, utf8 usw Wert legen sollte. Bzw ReadStringFormat und sein BOM. Müsste man ja eigentlich um korrekt zu sortieren oder?
ReadString wandelt alle ausgelesenen Strings automatisch in das Zeichenformat um, das vom Executable genutzt wird. Du könntest also Fehler erhalten, wenn eine Datei mit UTF-8 kodiert ist und du nur ASCII oder Unicode im Programm nutzt.
Und ansonsten? Gibts Verbesserungsvorschläge? :)
Ja, nutze LinkedLists statt Arrays.
SebastianJu2
Beiträge: 180
Registriert: 24.09.2010 10:39

Re: Sortierprogramm fast fertig. Noch ein Fehler...

Beitrag von SebastianJu2 »

@Nic
Ja, nutze LinkedLists statt Arrays.
Ich habe mal über Linked Lists ein wenig gelesen. Das sind Sammlungen von Variablen wenn ich richtig verstehe. Was hat das für Vorteile? Schneller wird es vermutlich nicht sein da Arrays spezialisierter klingen im Vergleich und deswegen vermutlich besser optimiert sind. (nur eine Vermutung)
Außerdem müsste ich eine eigene Sortierfunktion schreiben mit allem was dazugehört da die Bibliothek der linked lists wohl keine solche Funktion im Angebot hat.
Was haben Linked Lists denn hier für Vorteile?
ReadString wandelt alle ausgelesenen Strings automatisch in das Zeichenformat um, das vom Executable genutzt wird. Du könntest also Fehler erhalten, wenn eine Datei mit UTF-8 kodiert ist und du nur ASCII oder Unicode im Programm nutzt.
OK, dann werde ich diese Funktionen nutzen. Sollte ich mich auch mit ReadStringFormat() beschäftigen?
Benutzeravatar
HeX0R
Beiträge: 3042
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win11 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2 + 3
Kontaktdaten:

Re: Sortierprogramm fast fertig. Noch ein Fehler...

Beitrag von HeX0R »

SebastianJu2 hat geschrieben: Unter anderem die Werte "a" und "A" und "sdf" und "SDF". Normalerweise sollten nur noch je ein Element vorhanden sein danach.
Wie kommst du denn darauf?
SortArray löscht doch keine Elemente, a und A werden lediglich direkt hintereinander sortiert.

Das mit deinen Flags ist auch nicht richtig.
SortArray möchte keine Kombination der Flags haben, sondern entweder oder.
c4s
Beiträge: 1235
Registriert: 19.09.2007 22:18

Re: Sortierprogramm fast fertig. Noch ein Fehler...

Beitrag von c4s »

SebastianJu2 hat geschrieben:Außerdem müsste ich eine eigene Sortierfunktion schreiben mit allem was dazugehört da die Bibliothek der linked lists wohl keine solche Funktion im Angebot hat.
Wenn ich im Editor "sort" eingebe zeigt mir die Auto-Vervollständigung "SortArray", "SortList", "SortStructuredArray", "SortStructuredList" an. Den Rest kannst du dir selber denken. :allright:
"Menschenskinder, das Niveau dieses Forums singt schon wieder!" — GronkhLP ||| "ich hogffe ihr könnt den fehle endecken" — Marvin133 ||| "Ideoten gibts ..." — computerfreak ||| "Jup, danke. Gruss" — funkheld
SebastianJu2
Beiträge: 180
Registriert: 24.09.2010 10:39

Re: Sortierprogramm fast fertig. Noch ein Fehler...

Beitrag von SebastianJu2 »

Code: Alles auswählen

Wie kommst du denn darauf?
SortArray löscht doch keine Elemente, a und A werden lediglich direkt hintereinander sortiert.
Stimmt ja... es löscht ja keine Duplikate sondern sortiert nur... dann funktioniert es ja doch...
Das mit deinen Flags ist auch nicht richtig.
SortArray möchte keine Kombination der Flags haben, sondern entweder oder.
(Ausserdem bekommst du 3, wenn du beide Checkboxen anhakst, was eh falsch wäre)
Das ist schon korrekt. Normalerweise sind solche Konstanten so gewählt dass die Summe der Werte wiederum genau auf die einzelnen gewählten Konstanten rückschließen läßt. Probiere es einfach mit dem Code den ich gepostet habe und du wirst sehen dass es funktioniert...
SebastianJu2
Beiträge: 180
Registriert: 24.09.2010 10:39

Re: Sortierprogramm fast fertig. Noch ein Fehler...

Beitrag von SebastianJu2 »

c4s hat geschrieben:
SebastianJu2 hat geschrieben:Außerdem müsste ich eine eigene Sortierfunktion schreiben mit allem was dazugehört da die Bibliothek der linked lists wohl keine solche Funktion im Angebot hat.
Wenn ich im Editor "sort" eingebe zeigt mir die Auto-Vervollständigung "SortArray", "SortList", "SortStructuredArray", "SortStructuredList" an. Den Rest kannst du dir selber denken. :allright:
Danke... ich hatte in der Linkedlist.pb gesucht und da ist das nicht drin...

Sind Linked Lists jetzt perfomanter oder warum sind sie Arrays vorzuziehen.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Sortierprogramm fast fertig. Noch ein Fehler...

Beitrag von NicTheQuick »

SebastianJu2 hat geschrieben:@Nic
Ja, nutze LinkedLists statt Arrays.
Ich habe mal über Linked Lists ein wenig gelesen. Das sind Sammlungen von Variablen wenn ich richtig verstehe. Was hat das für Vorteile? Schneller wird es vermutlich nicht sein da Arrays spezialisierter klingen im Vergleich und deswegen vermutlich besser optimiert sind. (nur eine Vermutung)
Außerdem müsste ich eine eigene Sortierfunktion schreiben mit allem was dazugehört da die Bibliothek der linked lists wohl keine solche Funktion im Angebot hat.
Was haben Linked Lists denn hier für Vorteile?
LinkedLists sind vereinfacht gesagt dynamische Arrays. Das heißt du kannst vorne, hinten oder zwischen drin ein Element einfügen ohne dich um die nachfolgenden zu kümmern. Im Grunde sind sie eine geordnete Liste und immer dann praktisch, wenn man vorher nicht weiß wie viele Element noch kommen werden. Somit hast du dir schon mal dein Redim gespart. Redim ist da viel langsamer als wenn du eine LinkedList verwenden würdest. Und dass es auch den hübschen Befehl 'SortList' gibt, weißt du jetzt ja auch.

"A" und "a" werden übrigens nicht zu einem Element, weil 'SortArray' nicht strikt sortiert. Bei einer strikten Sortierung würden gleichwertige Elemente zu einem werden. Aber "A" und "a" sind immer noch zwei verschiedene Sachen, auch wenn der genutzte Komparator sie als gleichwertig ansieht. Woher sollte 'SortArray' dann auch wissen, ob es jetzt "A" oder "a" behalten soll?
SebastianJu2
Beiträge: 180
Registriert: 24.09.2010 10:39

Re: Sortierprogramm fast fertig. Noch ein Fehler...

Beitrag von SebastianJu2 »

Dann werde ich mal auf linkedlists umstellen. Vorher messe ich aber noch die Zeit zum vergleichen...

Ja mit dem Duplikate löschen war ein Irrtum... ich hab gar nicht dran gedacht dass eine Casesortierung ja erst die Großbuchstaben und wenn die durch sind die kleinen Buchstaben in Reihenfolge bringt...
Benutzeravatar
HeX0R
Beiträge: 3042
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win11 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2 + 3
Kontaktdaten:

Re: Sortierprogramm fast fertig. Noch ein Fehler...

Beitrag von HeX0R »

SebastianJu2 hat geschrieben:
Das mit deinen Flags ist auch nicht richtig.
SortArray möchte keine Kombination der Flags haben, sondern entweder oder.
(Ausserdem bekommst du 3, wenn du beide Checkboxen anhakst, was eh falsch wäre)
Das ist schon korrekt. Normalerweise sind solche Konstanten so gewählt dass die Summe der Werte wiederum genau auf die einzelnen gewählten Konstanten rückschließen läßt. Probiere es einfach mit dem Code den ich gepostet habe und du wirst sehen dass es funktioniert...
O.k., die Hilfe ist falsch und ich hatte brain.exe noch nicht gestartet...
Dort müsste nicht stehen:
'Optionen' kann einer der folgenden Werte sein:
sondern:
'Optionen' kann eine Kombination der folgenden Werte sein:
Antworten