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
