Daten mit "0" als string verarbeiten

Anfängerfragen zum Programmieren mit PureBasic.
Syntacks_Error
Beiträge: 107
Registriert: 08.03.2009 16:08

Daten mit "0" als string verarbeiten

Beitrag von Syntacks_Error »

Möchte aus Nicht-Text-Dateien, die aber hier und da auch Text eingebettet haben, den Text extrahieren.
Dummerweisen enthalten die Dateien jede Menge "0", was die Stringfunktionen wohl als "Stringende" verstehen und meinen, ihre Arbeit da einstellen zu sollen.

Einzige gefundene Lösung bislang: Datei einlesen, bitweise auslesen und die "0" aussortieren:

Code: Alles auswählen

file_size = FileSize(dateiname$)
file_ID = readfile(#pb_any,dateiname$)
*Memory_ID = AllocateMemory(file_size)

Datei_lesen = ReadData(file_ID, *memory_ID, file_size)
 If datei_lesen
  For x = 0 To file_size
   a.c = PeekC(*memory_ID + x)
   If a.c  >  0
    test$ = test$ + Chr(a.c)
   EndIf
  Next
 EndIf
  
debug "Teststring: " + left(test$,100)
Leider ist diese Methode unziemlich langsam. Gibt es Besseres?
DarkDragon
Beiträge: 6291
Registriert: 29.08.2004 08:37
Computerausstattung: Hoffentlich bald keine mehr
Kontaktdaten:

Re: Daten mit "0" als string verarbeiten

Beitrag von DarkDragon »

Probiers mal damit:

Code: Alles auswählen

file_size = FileSize(dateiname$)
file_ID = ReadFile(#PB_Any, dateiname$)
*memory.Character = AllocateMemory(file_size)

datei_lesen = ReadData(file_ID, *memory, file_size)
If datei_lesen
  test$ = Space(file_size / SizeOf(Character))
  *testPointer.Character = @test$
  *memoryEnd = *memory + file_size
  While *memory < *memoryEnd
   If *memory\c  >  0
     *testPointer\c = *memory\c
     *testPointer + SizeOf(Character)
   EndIf
   *memory + SizeOf(Character)
  Wend
  test$ = Left(test$, *testPointer - @test$)
EndIf
 
Debug "Teststring: " + Left(test$,100)
Testen konnte ich es nicht, da ich keine Datei hab. Generell solltest du aber ein paar Abfragen mehr reinsetzen zum Beispiel was das öffnen der Datei betrifft. Ich würde auch auf Lof() statt FileSize setzen, da die Datei zwischendrin gelöscht werden könnte und dann willst du einen Speicherbereich von -1 reservieren.
Angenommen es gäbe einen Algorithmus mit imaginärer Laufzeit O(i * n), dann gilt O((i * n)^2) = O(-1 * n^2) d.h. wenn man diesen Algorithmus verschachtelt ist er fertig, bevor er angefangen hat.
Rokur
Beiträge: 167
Registriert: 29.12.2005 09:58
Computerausstattung: Intel Core2 Quad (4x2,4 GHz), 4096 MB RAM, GForce 8800GTX 786 MB
Windows XP 32 Bit, PureBasic 4.40 (x86)

Re: Daten mit "0" als string verarbeiten

Beitrag von Rokur »

Wie wärs wenn du anstatt dem Zeichenweisen zusammenbasteln alle 0-Bytes durch was anderes ersetzt? Dann kannst du anschliessend den ganzen Speicherbereich verwenden.

Also so in der Art:

Code: Alles auswählen

a.b = PeekB(*memory_ID + x)
If a = 0
  PokeB(*memory_ID + x, 255)
EndIf
test$ = PeekS(*memory_ID, file_size)
Anstatt 255 kannst du natürlich auch irgendwas anderes Einsetzen, z.B. Leerzeichen oder so.

PS: Vorsicht beim Datentyp Character, bei Unicode hat der 2 Bytes, ansonsten 1 Byte!
WinXP 32 Bit, PureBasic 4.40 (x86)
Syntacks_Error
Beiträge: 107
Registriert: 08.03.2009 16:08

Re: Daten mit "0" als string verarbeiten

Beitrag von Syntacks_Error »

Verblüffend, vielen Dank. Das ist gefühlte 1000* schneller als als meine Geschichte. Wieso eigentlich?

Habe noch vier :-) Fragen dazu:
Wie kriege ich den Speicher wieder frei? freemem(*memory) wirft bei allen möglichen Variationen (incl *memory.character) einen Fehler aus.
Was bedeutet eigentlich dieses \c?
Müßte es nicht vielleicht "test$ = Space(file_size *SizeOf(character))" statt "test$ = Space(file_size/SizeOf(character))" heißen, wenn unicode berücksichtigt werden soll?
Offenbar kann man beim rechnen den neuen wert weglassen, also "x+1" statt "x = x+1"?
DarkDragon
Beiträge: 6291
Registriert: 29.08.2004 08:37
Computerausstattung: Hoffentlich bald keine mehr
Kontaktdaten:

Re: Daten mit "0" als string verarbeiten

Beitrag von DarkDragon »

Syntacks_Error hat geschrieben:Verblüffend, vielen Dank. Das ist gefühlte 1000* schneller als als meine Geschichte. Wieso eigentlich?

Habe noch vier :-) Fragen dazu:
Wie kriege ich den Speicher wieder frei? freemem(*memory) wirft bei allen möglichen Variationen (incl *memory.character) einen Fehler aus.
Was bedeutet eigentlich dieses \c?
Müßte es nicht vielleicht "test$ = Space(file_size *SizeOf(character))" statt "test$ = Space(file_size/SizeOf(character))" heißen, wenn unicode berücksichtigt werden soll?
Offenbar kann man beim rechnen den neuen wert weglassen, also "x+1" statt "x = x+1"?
*memory ist nach der Routine verändert, also müsste man es so machen:

Code: Alles auswählen

file_size = FileSize(dateiname$)
file_ID = ReadFile(#PB_Any, dateiname$)
*memory.Character = AllocateMemory(file_size)
*oldMemory = *memory

datei_lesen = ReadData(file_ID, *memory, file_size)
If datei_lesen
  test$ = Space(file_size / SizeOf(Character))
  *testPointer.Character = @test$
  *memoryEnd = *memory + file_size
  While *memory < *memoryEnd
   If *memory\c  >  0
     *testPointer\c = *memory\c
     *testPointer + SizeOf(Character)
   EndIf
   *memory + SizeOf(Character)
  Wend
  test$ = Left(test$, *testPointer - @test$)
EndIf

Debug "Teststring: " + Left(test$,100)
FreeMemory(*oldMemory)
Die Pointer sind ja hier Strukturiert. Wenn du Alt+S drückst siehst du die vordefinierten Strukturen. Darunter Character mit c.c ;-) . Man greift also auf den Inhalt an der Adresse zu als ob es ein Character wäre.

file_size ist die komplette Dateigröße, mehr Raum wird nicht benötigt, also ist "*" falsch. Da wir ja in der Datei aber maximal file_size / SizeOf(Character) Daten vom Typ Character in Reihe haben stimmt das "/".

Ja beim Rechnen kann man das = weglassen so wie du es sagtest.
Angenommen es gäbe einen Algorithmus mit imaginärer Laufzeit O(i * n), dann gilt O((i * n)^2) = O(-1 * n^2) d.h. wenn man diesen Algorithmus verschachtelt ist er fertig, bevor er angefangen hat.
Syntacks_Error
Beiträge: 107
Registriert: 08.03.2009 16:08

Re: Daten mit "0" als string verarbeiten

Beitrag von Syntacks_Error »

Aja. Vielen Dank nochmal, auch an den anderen Poster.
Antworten