Seite 1 von 1

Komisches Verhalten von WriteString in Kombination mit StrF

Verfasst: 09.11.2012 12:28
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...

Re: Komisches Verhalten von WriteString in Kombination mit S

Verfasst: 09.11.2012 13:14
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.

Re: Komisches Verhalten von WriteString in Kombination mit S

Verfasst: 09.11.2012 13:49
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

Re: Komisches Verhalten von WriteString in Kombination mit S

Verfasst: 09.11.2012 14:54
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.

Re: Komisches Verhalten von WriteString in Kombination mit S

Verfasst: 09.11.2012 15:02
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 ?

Re: Komisches Verhalten von WriteString in Kombination mit S

Verfasst: 15.11.2012 12:24
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