Komisches Verhalten von WriteString in Kombination mit StrF

Für allgemeine Fragen zur Programmierung mit PureBasic.
wolfgang.ebersbach
Beiträge: 6
Registriert: 21.02.2012 23:04

Komisches Verhalten von WriteString in Kombination mit StrF

Beitrag von wolfgang.ebersbach »

Hallo Forum,

ich habe ein komisches Phaenomen. Ich mache eine Binaerdatei auf, lese die einzelnen Bytes nach Position ein, mache ein bisserl was damit und schreibe sie als ASCII, formatiert mit Str() zurueck. In der Binaerdatei stehen immer 16 Bytes die zu 8 Words zusammengefasst werden muessen (MSB first) und an 17-ter Stelle noch ein einzelnes Byte.

Edit: Sollte dazusagen dass das MSByte im 2-er komplement vorliegt, d.h. das MSBit dieses MSByte stellt das Vorzeichen dar.
Wenn ich dieses MSByte also mit MSByte << 8 in eine Variable vom Typ .w (word) shifte, erwarte ich dass das Vorzeichen ab diesem Zeitpunkt "auftaucht". Mit float geht das auch. Leider ist auch das nicht zu verstehen, denn float hat ja 4 Bytes, das MSBit des MSByte kommt somit ja gar nicht an Position 32, wo das Sign ist, sondern nur an Position 16. Geht aber trotzdem...

Der Code ist dieser:

Code: Alles auswählen

Procedure.s LoadAndConvertFile(FileName.s,StoragePath.s)
  AsciiFileName.s
  FilePointer.d = 0
  SingleByte.a
  WordCounter.d
  ResultInt.w = 0
  lines.q = 0
  RdByte.a = 0
  Bit.a = 0
  OldBit.a = 0
  ByteCounter.a = 0
  BitCounter.a = 0
  Voltage.f = 0
  
    If FileName <> ""
      AsciiFileName = GetFilePart(FileName)
      AsciiFileName = ReplaceString(AsciiFileName,".csv","_ascii.txt")
      AsciiFileName = StoragePath + AsciiFileName  
      If ReadFile(#InFile,FileName)
        Open_MessageWindow()
        FileLength = Lof(#InFile)
        SetGadgetText(#MessageText,"Reading and converting file " + FileName +". This may take a while as the file is " + StrU(FileLength) + " bytes big.")
        StopPosition = Lof(#InFile)/17            ; set stop position To End of file
        StartPosition = 0
        DataToShow = StopPosition
        SetGadgetAttribute(#PositionScrollBar,#PB_ScrollBar_Maximum,StopPosition)
        SetGadgetAttribute(#PositionScrollBar,#PB_ScrollBar_PageLength,StopPosition)
        SetGadgetAttribute(#ProgressBar,#PB_ProgressBar_Maximum,StopPosition)
        SetGadgetAttribute(#MessageProgress,#PB_ProgressBar_Maximum,StopPosition)

        If OpenFile(#AsciiFile,AsciiFileName)
          While Eof(#InFile) = 0
            FileSeek(#InFile,FilePointer)       ; to the next byte
            RdByte.a = ReadByte(#InFile)            ; read one byte
            OldBit.a = Bit.a
            Bit.a = RdByte.a
            If ByteCounter.a = 1                  ; have read two bits
              ByteCounter.a = 0
              ResultInt.w = OldBit.a << 8
              ResultInt.w = ResultInt.w | Bit.a
              voltage.f = ResultInt.w / 1
              WriteString(#AsciiFile,Str(ResultInt.w) + ";")
             ; WriteString(#AsciiFile,StrF(voltage.f) + ";")
            Else
              ByteCounter.a = ByteCounter.a + 1
            EndIf
            BitCounter.a = BitCounter.a + 1       ; next byte
            If BitCounter.a = 17                  ; if this was the last of the 17 data bytes
              lines = lines + 1
              SetGadgetState(#MessageProgress,lines)
              ByteCounter.a = 0
              BitCounter.a = 0                    ; reset bit counter
              WriteString(#AsciiFile,StrU(RdByte.a,#PB_Ascii))
              WriteStringN(#AsciiFile," ")        ; write a CRLF to the out file
            EndIf
            FilePointer.d = FilePointer.d + 1       ; move infile file pointer 
          Wend
          Debug "processed " + StrU(lines,#PB_Quad) + " lines"
          CloseFile(#AsciiFile)
          CloseFile(#InFile)
        EndIf
        CloseWindow(#MessageWindow)
      Else
        MessageRequester("Error","Unable to open file " + FileName + " for reading.")
      EndIf
    EndIf
    ProcedureReturn AsciiFileName
  EndProcedure

Das Irre ist nun: Wenn ich das AsciiFile mit dem auskommentierten WriteString schreibe (d.h. einen Float mit StrF() konvertiert), geht alles wie es soll. Wenn ich hingegen den Code so wie er jetzt ist laufen lasse (mit Str() ein Word konvertiert) dann wird das geschrieben AsciiFile laenger als es sollte, nach den korrekten Daten kommt noch ein groesserer Block mit Muell der aussieht als haette ich irgendwie einen Pufferueberlauf oder sowas.
Die Dabugausgabe zeigt mir die korrekte Anzahl Zeilen an. Nur: In der Datei sind es trotzdem viel mehr...

Sorry fuer die verkorksten Varaiblennamen, das wird gefixt sobald es laeuft...

Natuerlich kann ich es mit Floats machen, ich will aber keine Floats verwenden wenn ich doch nur Word brauche...

Bin fuer jeden Tipp dankbar...

So sieht das ASCII file nach dem Ende der gelesenen Binaerdaten aus, wenn ich das mit Str() speichere:

Code: Alles auswählen

1064;1065;1071;1057;1060;1068;1065;1061;255 
1064;1070;1068;1054;1058;1069;1058;1064;255 
1063;1067;1074;1052;1061;1070;1065;1058;255       <- Hier sind die realen Daten zu Ende
64.0000000000;1071.0000000000;1052.0000000000;1061.0000000000;1070.0000000000;1063.0000000000;1061.0000000000;255   <- Ab hier Muell der aber irgendwie auf den Originaldaten basiert...
1069.0000000000;1070.0000000000;1071.0000000000;1057.0000000000;1062.0000000000;1068.0000000000;1059.0000000000;1061.0000000000;255 
1068.0000000000;1070.0000000000;1068.0000000000;1054.0000000000;1063.0000000000;1072.0000000000;1058.0000000000;1057.0000000000;255 

Es geht wie gesagt weiter als die Anzahl Zeilen die mir die Debugausgabe anzeigt. Bin voellig verwirrt...
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: Komisches Verhalten von WriteString in Kombination mit S

Beitrag von ts-soft »

Hab das Problem nicht ganz verstanden, aber die Dateiposition in einem Double zu halten ist wohl :o
Ein Quad wäre der geeignetet Typ.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
wolfgang.ebersbach
Beiträge: 6
Registriert: 21.02.2012 23:04

Re: Komisches Verhalten von WriteString in Kombination mit S

Beitrag von wolfgang.ebersbach »

Hallo ts-soft,

yepp, stimmt, habs in Quad geaendet. Aendert aber nix am Verhalten:

Schreibe ich das ASCII file mit WriteString(#AsciiFile,StrF(FloatVar)) geht es,
schreibe ich das ASCII file mit WriteString(#AsciiFile,Str(WardVar)) wird das ASCII file viel zu gross, nach den erwarteten Daten kommt noch ein Haufen komisches Zeugs. Siehe Originalpost.

Gruss,
Wolfgang
Benutzeravatar
bobobo
jaAdmin
Beiträge: 3875
Registriert: 13.09.2004 17:48
Kontaktdaten:

Re: Komisches Verhalten von WriteString in Kombination mit S

Beitrag von bobobo »

Das wirklich irre ist, dass die AusgabeDatei nicht neu angelegt wird, sondern einfach in die vorhande reingemichelt wird.
Das alte Rest bleibt dann natürlich drin.
‮pb aktuel 6.2 windoof aktuell und sowas von 10
Ich hab Tinnitus im Auge. Ich seh nur Pfeifen.
wolfgang.ebersbach
Beiträge: 6
Registriert: 21.02.2012 23:04

Re: Komisches Verhalten von WriteString in Kombination mit S

Beitrag von wolfgang.ebersbach »

Hallo bobobo,

boboboaaa, ey ! In der Tat, wenn ich CreateFile() nehme ist das Phaenomen weg.
OK, geht, aber VERSTANDEN habe ich das nicht.

1) Wieso der Unterschied ob ich ein Str(WordVariable) oder ein StrF(FloatVariable) schreibe.
2) Wieso passiert's mit OpenFile() auch wenn vorher kein File existiert hat ?
3) Wieso passiert's mit OpenFile() obwohl ich seit Stunden in dem immer gleichen Verzeichnis mit dem immer gleichen Binaerfile arbeite ?

Trotzdem Danke und einen schoenen Tag noch,

Wolfgang


P.s.: Wie bekomme ich den Absolutwert von einem Word ? In der Hilfe steht ausdruecklich, dass Abs() mit grossen Integern nicht funktioniert. Was ist "gross" ? Ist ein Word gross ?
Benutzeravatar
bobobo
jaAdmin
Beiträge: 3875
Registriert: 13.09.2004 17:48
Kontaktdaten:

Re: Komisches Verhalten von WriteString in Kombination mit S

Beitrag von bobobo »

Na so schwer ist das aber eigentlich nicht zu verstehen. Hab ich doch schon geschrieben.

Openfile erzeugt nur beim ersten Mal eine neue Datei ..die ist dann auch ok.
Allerdings wird die ab dem zweiten Mal nochmal geöffnet und vom Anfang her
überschrieben und DAS erzeugt den merkwürdigen Rest am Ende der Datei.


Als Trost kannst Du Dir zugute halten, dass das Programm immerhin genauso
funktioniert wie Du es es geschrieben hast
:bounce:

Irgendwann erfinde ich mal die Machmal() -Prodecure .. die beherrscht dann auch sowas
‮pb aktuel 6.2 windoof aktuell und sowas von 10
Ich hab Tinnitus im Auge. Ich seh nur Pfeifen.
Antworten