Platzerhalter in HTML- oder RTF-Datei ersetzen

Anfängerfragen zum Programmieren mit PureBasic.
bin_neu_hier
Beiträge: 105
Registriert: 06.03.2019 21:52

Platzerhalter in HTML- oder RTF-Datei ersetzen

Beitrag von bin_neu_hier »

Hallo Leute,

ich möchte Folgendes tun:

Eine Datei (entweder RTF oder HTML, kann beides vorkommen) in einen String einlesen, darin einige Ersetzungen mit Replacestring() vornehmen (vorher eingesetzte Platzhalter, der String wird also an Länge zunehmen, grob gepeilt so um die 10%) und dann wieder je nach Quelldatei als HTML- oder RTF-Datei speichern. Die Platzhalter sehen so aus: @xxx@. xxx ist die Nummer eines Gadgets - einige Platzhalter können in einer Datei auch mehrfach vorkommen.

Wie kann ich sicherstellen, dass die ganze Datei geladen wird (nicht dass zwischendrin ein "Null" den Ladevorgang beendet)? Könnte so ein String auch ein "Null" oder andere Zeichen, deren Ascii-Code für Steuerzwecke verwendet werden, aufnehmen? Könnte sowas überhaupt in HTML- oder RTF-Dateien vorkommen?

Die größte der Dateien ist rund 120 kb groß, kann das ein String noch aufnehmen? Wäre da auch noch "Luft nach oben"?

Mein Projekt wird am Ende nur einen einzigen User haben, die Anzahl der Credits (die Helfer aus diesem Board) ist also schon jetzt um einiges höher!

Edit by NicTheQuick: Titel leichter auffindbar gemacht
Bin mit 21 erstmals mit Computern in Kontakt gekommen und konnte mich daher in meiner Jugend ganz auf den Alkohol konzentrieren. Bin nun seit fast 40 Jahren programmiertechnisch konstant auf Anfänger-Level, konnte jedoch beim Thema Alkohol eine gewisse Virtuosität erreichen.
Irgendwas muss man ja gut können.
Benutzeravatar
Sylvia
verheiratet<br>1. PureGolf-Gewinner
Beiträge: 487
Registriert: 29.08.2004 09:42
Wohnort: Old Europe

Re: Heute wieder mal ein "Wie macht man das eigentlich?"

Beitrag von Sylvia »

Hi bin_neu_hier,

vergiss den Kram mit Strings...geht nicht/zu umständlich.

Habe jetzt kein Bock, hier einen fertigen Code hinzulegen, aber ich würde mit AllocateMemory() , OpenFile(), ReadData() die Datein einlesen und mit den Memory-Befehlen arbeiten. Musst halt ein Replace emulieren. Danach wieder mit WriteData() abspeichern. Musst halt immer wissen, wo im Speicher dann die Daten enden nach der Veränderung. Nicht sparen mit AllocateMemory()! Weisst ja vorher nicht, was am Ende rauskommt
Zuletzt geändert von Sylvia am 08.04.2019 19:51, insgesamt 1-mal geändert.
Basic Pur = PureBasic
Benutzeravatar
mk-soft
Beiträge: 3695
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Heute wieder mal ein "Wie macht man das eigentlich?"

Beitrag von mk-soft »

HTML und RTF Dateien sind im weiten Sinne Textdateien mit Steuerzeichen oder Formatierter Text.
Ein Zeichen NULL (Wert 0) kann (und darf) in einer Textdatei nicht vorkommen, da diese in Verarbeitung von Strings IMMER ein ende ist.

Dann noch die Zeichenformatierung (BOM) beachten. Ascii, UTF8, Unicode, etc
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
mk-soft
Beiträge: 3695
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Heute wieder mal ein "Wie macht man das eigentlich?"

Beitrag von mk-soft »

Sylvia hat geschrieben:Hi bin_neu_hier,

vergiss den Kram mit Strings...geht nicht/zu umständlich.

Habe jetzt kein Bock, hier einen fertigen Code hinzulegen, aber ich würde mit AllocateMemory() , OpenFile(), ReadData() die Datein einlesen und mit den Memory-Befehlen arbeiten. Musst halt ein Replace emulieren. Danach wieder mit WriteData() abspeichern. Musst halt immer wissen, wo im Speicher dann die Daten enden nach der Veränderung. Nicht sparen mit AllocateMemory()! Weisst ja vorher nicht, was am Ende rauskommt
Sehr hilfreich hier im Anfängerforum...
Natürlich geht es und so umständlich ist es auch wieder nicht, wenn man weis was man ersetzen möchte.
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
bin_neu_hier
Beiträge: 105
Registriert: 06.03.2019 21:52

Re: Heute wieder mal ein "Wie macht man das eigentlich?"

Beitrag von bin_neu_hier »

Danke Sylvia, bestimmt gut gemeint, aber ... äh ... ich bin noch nicht so weit, den String-Kram vergessen zu können. Werde wahrscheinlich auch nie in der Championsleague der Programmierer landen, da emulier ich mir mal nix vor.

Aber vielleicht kann doch noch jemand helfen. Brauche einen Schubs von Euch in die richtige Richtung. Mit den HTML-Dateien komme ich klar, die werden korrekt geladen, manipuliert und gespeichert, nur bei den RTF-Dateien komme ich nicht weiter. Mein Code-Fragment zeigt die Stelle, an der erkannt wird, dass eine RTF-Datei geladen, manipuliert und gespeichert werden soll.

Code: Alles auswählen

  Case ".rtf"
        flagg = #PB_Ascii    ;damit ich beim ausprobieren nicht zig-mal ändern muss

        err = ReadFile(#loadfilenum, file$, flagg)
        If err <> 0
          
          While Eof(#loadfilenum) = 0
            x$ = x$ + Chr(ReadCharacter(#loadfilenum, flagg))    
          ;  x$ = x$ + ReadString(#loadfilenum, flagg)
            
          Wend
          CloseFile(#loadfilenum)
          
; jetzt string in x$ mehrfach manipulieren mit Replacestring (zwischen 15 und 33 mal, je nach geladener Datei) 

          err = CreateFile(#savefilenum, dateiname$, flagg)
          If err <> 0
            WriteString(#savefilenum, x$, flagg)
            CloseFile(#savefilenum)
            
          Else
            ;konnte nicht geschrieben werden
          EndIf
                   
        Else
          ;konnte nicht geöffnet werden
        EndIf
        
Wenn mit

Code: Alles auswählen

 x$ = x$ + Chr(ReadCharacter(#loadfilenum, flagg))    
geladen wird, dauert der Ladevorgang sehr lange, so um die 15 Sekunden für 100 KB. Debug x$ zeigt den Inhalt der RTF-Datei ziemlich genau so wie das in Notepad gezigt wird.

Wenn aber mit

Code: Alles auswählen

 x$ = x$ + ReadString(#loadfilenum, flagg)
geladen wird, dauerts kaum 1 Sekunde, aber Debug zeigt's irgendwie komprimiert an, Zeilenumbrüche wie bei mit Readcharakter geladen fehlen. Muss schon mal was "im Busch sein".

Wer kann mir sagen, wie man eine RTF-Datei richtig und einigermaßen zügig in eine Stringvariable einliest und wie man den String nach diversen Manipulationen wieder als RTF-Datei speichert?
Bin mit 21 erstmals mit Computern in Kontakt gekommen und konnte mich daher in meiner Jugend ganz auf den Alkohol konzentrieren. Bin nun seit fast 40 Jahren programmiertechnisch konstant auf Anfänger-Level, konnte jedoch beim Thema Alkohol eine gewisse Virtuosität erreichen.
Irgendwas muss man ja gut können.
Benutzeravatar
Bisonte
Beiträge: 2427
Registriert: 01.04.2007 20:18

Re: Heute wieder mal ein "Wie macht man das eigentlich?"

Beitrag von Bisonte »

probiers mal mit dem Flag : #PB_File_IgnoreEOL

Code: Alles auswählen

Case ".rtf"
  flagg = #PB_Ascii    ;damit ich beim ausprobieren nicht zig-mal ändern muss
  
  err = ReadFile(#loadfilenum, file$, flagg)
  If err <> 0
    
    x$ = ReadString(#loadfilenum, flagg|#PB_File_IgnoreEOL)
    
    CloseFile(#loadfilenum)
    
    ; jetzt string in x$ mehrfach manipulieren mit Replacestring (zwischen 15 und 33 mal, je nach geladener Datei)
    
    err = CreateFile(#savefilenum, dateiname$, flagg)
    If err <> 0
      WriteString(#savefilenum, x$, flagg)
      CloseFile(#savefilenum)
    Else
      ;konnte nicht geschrieben werden
    EndIf
    
  Else
    ;konnte nicht geöffnet werden
  EndIf
P.S.: In Ermangelung einer rtf Datei und eines lauffähigen Codes konnte nicht auf Funktion getestet werden ;)
PureBasic 6.04 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom​​
bin_neu_hier
Beiträge: 105
Registriert: 06.03.2019 21:52

Re: Heute wieder mal ein "Wie macht man das eigentlich?"

Beitrag von bin_neu_hier »

Hallo Bisonte,

ja, das war - wieder einmal - ein guter Tipp von Dir :allright: ! Hast mir schon (mindestens) 2x über die Straße geholfen, herzlichen Dank dafür!
Bin mit 21 erstmals mit Computern in Kontakt gekommen und konnte mich daher in meiner Jugend ganz auf den Alkohol konzentrieren. Bin nun seit fast 40 Jahren programmiertechnisch konstant auf Anfänger-Level, konnte jedoch beim Thema Alkohol eine gewisse Virtuosität erreichen.
Irgendwas muss man ja gut können.
Häns
Beiträge: 47
Registriert: 27.10.2007 14:30
Wohnort: Kölle

Re: Heute wieder mal ein "Wie macht man das eigentlich?"

Beitrag von Häns »

Leute wie Du, @neu_hier, wären froh und dankbar, wenn sie bei der Suche anhand Titel mit aussagekräftigen Stichworte wie "Datei von String auf HTML" entsprechende Lösungen finden können, und nicht anhand deines Titels "heute mal wieder...".

Es wäre daher nett, wenn Du den Titel änderst. Die anderen Neulinge oder sonstigen alten Säcke wie mich wären dankbar. 8)

Gruß, Häns
PB 5.6
Windows 7 Professional
Toshy
Beiträge: 710
Registriert: 22.03.2005 00:29
Computerausstattung: Computer und Strom vorhanden
Wohnort: LK Wolfenbüttel

Re: Heute wieder mal ein "Wie macht man das eigentlich?"

Beitrag von Toshy »

Das Thema hat sich jetzt zwar erledigt, für einen Neuling möchte ich allerdings noch etwas anmerken:

Code: Alles auswählen

         While Eof(#loadfilenum) = 0
            x$ = x$ + Chr(ReadCharacter(#loadfilenum, flagg))   
          ;  x$ = x$ + ReadString(#loadfilenum, flagg)
           
          Wend
Wenn du nun eine 100kb Datei hast, sind das "rund" 100 000 Bytes.
nutzt man

Code: Alles auswählen

x$ = x$ + Chr(ReadCharacter(#loadfilenum, flagg))  
wird nun ein character, also EIN oder ZWEI Bytes auf einmal eingelesen.
Das bedeutet auch, die Schleife läuft 50 000 mal oder 100 000 mal durch. Und immer wird nur ein Byte oder zwei gelesen!!

nutzt man

Code: Alles auswählen

x$ = x$ + ReadString(#loadfilenum, flagg)
Wir im korrekten Falle (Flag siehe oben) die ganze Datei auf eimal geladen. Wenn ich mich nicht irre, wird geladen bis ein EOL kommt, was wohl ein Nullbyte ist oder eventuell UTF oder so kann es auch was anderes sein. ich errinnere mich da nicht.

1. Wird hier auf jeden FAll in EINEM BLOCK gelesen (es sei den, was hier so scheint ein EOL in der Mitte steht) und das geht natürlich schneller. bei SSD merkt man es etwas weniger als bei normalen HDDs. bemerkbar ist es dennoch.
2. wird bei readchar jedes byte ausgelesen und gespeichert (außer nullbytes vermutlich). bei readstring allerdings nicht, falls eol im text sind. und diese werde dann auch nicht mehr im string gespeichert, da es "steuerzeichen" für PB sind (vereinfacht gesagt). es wird also nicht eins zu eins kopiert.

Was mir jetzt in den Sinn kommt ist allerdings, weshalb sind in der das EOLs drinn!? Das weißt doch auf einen FEHLER hin.
Entweder in der Datei, oder was ich eher vermute in deinem Code. Vermutlich nutzt dein kompeliertes PRogramm einen anderen Zeichensatz als die Datei!

Ich würde das noch mal überprüfen, alten Code nehmen der nicht ging und mal raus finden woran es lag.

Ach ja, und wie schon jemand gebeten hat. Passe den Titel deine ersten Beitrages mal an. einfach im Beitrag auf "ändern" klicken.

So was wie "[erledigt]readstring / readchar HTML und RTF auslesen. Problem."
1. AMD Athlon II X2 250P,4GB-RAM,WinXP
2. Notebook,500mhz,128MB-RAM,WINXP
3. WHS 2003
Inet: 6Mbit Down/386Kbit Up,Flat
PB4.60
Messenger: Trillian
H.Brill
Beiträge: 356
Registriert: 15.10.2004 17:42
Wohnort: 66557 Neunkirchen

Re: Heute wieder mal ein "Wie macht man das eigentlich?"

Beitrag von H.Brill »

1 KB = 1024 Byte
EOL = END OF LINE
Das ist ein Chr(13) + Chr(10) -> LINEFEED
So wird in Textdateien das Ende einer einzelnen Zeile markiert.

EOF = END OF FILE
Markiert das Ende einer Datei.

Das NULLBYTE markiert nur das Ende eines Strings in PB.
Also muß man aufpassen, was man mit welchen Lesebefehlen
aus einer Datei liest. Bei ReadString handhabt PB das so, daß
man bis ans Ende der Zeile den String bekommt.

Während ReadCharacter entsprechend des Formats (Ascii, Unicode, Utf8)
ein oder mehr Zeichen lesen kann, liest ReadByte nur ein einzelnes Zeichen.
Also auch immer beachten, wie die Datei codiert ist (Ascii, utf8, Unicode).
PB 5.60
Antworten