Alarmsturfe 1A
-
Ich beschäftige mich z.Z. mit der Speicher- und Spielstandsmanipulation (mehr Geld, höhere Skills usw.) und habe mir einen Hex-Editor besorgt. Mit dem Ding kann man sehr viel verändern, aber jetzt habe ich ein Problem mit dem Einlesen von Dateien.
Vor einigen Wochen habe ich ein Programm geschrieben, dass die Zeichenverschlüsselung der Spielstandsdateien in Folgen von Bytes umwandelt. Dies musste ich tun, weil mein Hex-Editor auf DOS-Ebene programmiert wurde und ich die Bytes nicht einfach in eine *.txt-Datei kopieren konnte. Doch selbst als mein Programm lief, hatte es Macken. So hat es, wenn ein Byte den Wert 26 (0x1A) hatte, dies komischerweise als -1 (0xffffffff) interpretiert, das eofbit des Streams auf 1 gesetzt und das Laden abgebrochen. Also habe ich eine ANSI-Tabelle zu Rate gezogen und erfahren, dass das fehlerhafe Byte als '→' (ich weiss nicht, ob das Zeichen richtig dargestellt wurde, aber es sollte ein nach rechts zeigender Pfeil sein →) interpretiert wird. Damals habe ich mir nicht sehr viel Gedanken darüber gemacht, weil man dieses Zeichen ganz leicht austauschen kann.
Am Wochenende habe ich dann zum ersten Mal einen Spielstand manipuliert, der eine Prüfsumme hatte (d.h., alle Bytes werden miteinander addiert, und das Ergebnis ist die Prüfsumme.). Dabei habe ich einen meiner Spielstände abgeknallt, weil ich eben diese Prüfsumme nicht verändert habe. Also habe ich ein Programm geschrieben, dass jedes Byte einliesst, es entsprechend berechnet (ich musste ein paar Bitverschiebungen einbauen) und das Ergebnis so, wie es gebraucht wird (von rechts nach links, eine Leerstelle pro Byte) ausgibt. Beim dritten Testlauf ist mir dann aufgefallen, dass es wieder Probleme mit dem Stream gibt. Schnell fand ich heraus, was der Fehler war: Das fehlerhafte 1A.
Langsam hatte ich genug von diesem Zeichen, und ich schrieb dieses Programm, und herauszufinden, warum mein PC spinnt:
#include <iostream> #include <fstream> using namespace std; typedef unsigned char BYTE; typedef unsigned short WORD; ifstream FIN1; ifstream FIN2; int main() { BYTE bCHARACTER; WORD wCOUNTER; FIN1.open("A.bin",ios_base::in); if(!FIN1) { cout<<"Fehlerhafter Stream!\n"; return 1; } cout<<"Erster Stream, normal:\n\n"; for(wCOUNTER=0x0;wCOUNTER<0x20;wCOUNTER++) { bCHARACTER=FIN1.get(); cout<<hex<<wCOUNTER<<"\t="<<(WORD)bCHARACTER<<"\t="<<bCHARACTER<<endl; } FIN1.close(); FIN2.open("A.bin",ios_base::in); cout<<"\n\n"; cout<<"Zweiter Stream, modifiziert:\n\n"; if(!FIN2) { cout<<"Fehlerhafter Stream!\n"; return 1; } for(wCOUNTER=0x0;wCOUNTER<0x20;wCOUNTER++) { if(wCOUNTER==0x1A) { cout<<endl; FIN2.seekg(2,FIN2.ios_base::cur); continue; } bCHARACTER=FIN2.get(); cout<<hex<<wCOUNTER<<"\t="<<(WORD)bCHARACTER<<"\t="<<bCHARACTER<<endl; } FIN2.close(); cin.get(); return 0; }Inhalt von A.bin
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1FDieses Programm soll die Zeichen, die in A.bin stehen, einlesen und ausgeben. Beim ersten Stream spinnt mein PC, wenn der Datenzeiger auf das Zeichen 1A zeigt. Danach gibt es nur noch 0xffff. Selbst das Schliessen und wieder Öffnen des Streams bringt nichts. Beim zweiten Stream habe ich versucht, das Zeichen mit der Methode FIN2.seekg(2,ios_base::cur), die den Dateizeiger um 2 Stellen nach links verschiebt, zu umgehen. Pustekuchen, denn nach 0x19 (0x1B) kommt wieder nur 0xffff.
Weiss jemand, was hier los ist???
-
$1a ist das EOF-Kennzeichen einer Textdatei.
Du solltest die Daten binär einlesen (mit open, read etc) und nicht als Stream.
-
Ich dachte immer, als EOF-Zeichen wird -1 verwendet (alles, was grösser als 0xFF ist). Wie auch immer, ich werd's ausprobieren.
-
FIN1.open( "A.bin", ios_base::in | ios_base::binary );
Versuchs mal so.