Maschienencode konvertierung
-
So gehts jetzt
Aber der schreibt vor der 90 erst noch ffff ich glaub ich mach das mit C das geht leichter. ^^
#include <iostream> #include <fstream> using namespace std; int main(int argc, char* argv[]) { char save[200] ; char var; int j; ofstream file ( "exit.bin" ); file << "\x90"; file.close(); ifstream f2 ( "exit.bin" ); f2 >>save; f2.close(); var=save[0]; cout<<var<<endl; cout<< hex << static_cast<int>(var); system("PAUSE"); return 0; }
-
Weil du mit C++ nicht umgehen kannst, geht es mit C also leichter?
-
#include <iostream> #include <fstream> #include <iomanip> int main(int argc, char** argv) { std::ofstream os("exit.bin"); os << '\x90' << std::flush; std::ifstream is("exit.bin"); unsigned char tmp; is >> tmp; std::cout << std::hex << static_cast<unsigned>(tmp) << std::endl; }Filestreams müssen nicht geschlossen werden, die schließen sich im Destruktor selbst. Außerdem musst du unsigned char verwenden.
-
Habs jetzt mit C++ hinbekommen ^^
Aber wann benutz mann denn .close(); ?
Benutzen die das hier nur weil man die Datei mit .open öffnet ?
http://www.cplusplus.com/reference/iostream/ifstream/close/
Ich kannte das bisher immer nur so das man bei ifstream und ofstream die Streams mit .close(); schließen muss.
Ansonsten Debugge ich es nachher mal dann sehe ich es ja wie es wirklich funktioniert.
-
Die benutzt man in der Regel gar nicht. Im Konstruktor öffnen, im Destruktor schließen, nennt sich RAII.
-
Hast du dein Beispiel mal getestet? Ich kann mir gut vorstellen, dass das eher ein Fall ist, wo man close() anwenden muss. Du öffnest eine Datei zum Schreiben und willst sie ein zweites Mal zum Lesen öffnen, bevor sie durch den Destruktor geschlossen wurde. Es ist immer sinnvoll, wenn man die Objektlebensdauer nicht einschätzen kann oder sie länger ist, Ressourcen nur solange zu halten, wie man sie benötigt.
-
Ergänzung:
Der Destruktor ist (auch) als Absicherung gedacht, damit die Ressourcen auch wirklich wieder frei gegeben werden.
-
Paul Müller schrieb:
Hast du dein Beispiel mal getestet? Ich kann mir gut vorstellen, dass das eher ein Fall ist, wo man close() anwenden muss. Du öffnest eine Datei zum Schreiben und willst sie ein zweites Mal zum Lesen öffnen, bevor sie durch den Destruktor geschlossen wurde. Es ist immer sinnvoll, wenn man die Objektlebensdauer nicht einschätzen kann oder sie länger ist, Ressourcen nur solange zu halten, wie man sie benötigt.
Du hast RAII nicht verstanden. Solche Fälle sollte man gar nicht erst aufkommen lassen. Ich sehe auch kein Szenario wo man dazu gezwungen wäre.
-
SeppJ schrieb:
Du hast RAII nicht verstanden.
Geht das schon wieder los?
SeppJ schrieb:
Solche Fälle sollte man gar nicht erst aufkommen lassen.
Dann beschwer dich bei 314159265358979 und sag ihm, dass sein Design scheiße ist. Ich würds in dem konkreten Fall ganz genauso machen, weil http://en.wikipedia.org/wiki/KISS_principle.
SeppJ schrieb:
Ich sehe auch kein Szenario wo man dazu gezwungen wäre.
Die Verwendung von Ressourcen muss nicht zwangsläufig mit der Lebensdauer einer Funktion einher gehen. Dazu kannst du dir noch mal das Beispiel von 314159265358979 ansehen.
-
Natürlich könnte man statt des Flushens die File explizit closen.
-
Dann ist aber immer noch das File-Handle offen. Und es gibt Möglichkeiten Dateien so zu öffnen, dass sie kein weiteres Mal geöffnet werden können. Wenn wir aber von Ressourcen sprechen, dann meinen wir nicht nur Dateien. Zum Beispiel bei einem Drucker macht es gar kein Sinn vorher einen neuen Druckauftrag zu versenden, bevor der alte noch nicht abgeschlossen ist.
-
Dein Beispiel ist falsch. Wenn ich mehrere Seiten drucken will, lege ich die Aufträge in eine Auftrags-queue.
-
Paul Müller schrieb:
SeppJ schrieb:
Du hast RAII nicht verstanden.
Geht das schon wieder los?
Bis du es endlich verstehst
. Das ist kein Gefrickel das mal in seltenen Ausnahmefällen funktioniert. Das ist eine grundlegende Technik, die eigentlich immer für alles funktioniert (du magst exotische Ausnahmefälle konstruieren können, aber FileHandles, Drucker und vor allem Arbeitsspeicher gehören nicht dazu!).SeppJ schrieb:
Solche Fälle sollte man gar nicht erst aufkommen lassen.
Dann beschwer dich bei 314159265358979 und sag ihm, dass sein Design scheiße ist.
Ist es auch, denn seine Variablen sind nicht so lokal wie sie sein sollten:
#include <iostream> #include <fstream> #include <iomanip> int main(int argc, char** argv) { { std::ofstream os("exit.bin"); os << '\x90' << std::flush; } // os wird hiernach nie wieder gebraucht, also lokal machen. { std::ifstream is("exit.bin"); unsigned char tmp; is >> tmp; std::cout << std::hex << static_cast<unsigned>(tmp) << std::endl; } // is und tmp werden hiernach nie wieder gebraucht, also lokal machen }Zack, alle Probleme gelöst indem 4 Zeichen eingefügt wurden. Gleichzeitig gezeigt, dass man über die Programmstruktur nachgedacht hat. Und vor allem kann jetzt nirgends mehr irgendwas schiefgehen.
-
Ist das euer ernst mit den Klammern oder ein schlechter Scherz?

-
Nein dein Ansatz ist falsch. Die Auftrags-Queue ist nicht der Drucker, die Auftrags-Queue bedient nur den Drucker. Damit hält sie das Problem von dir fern, indem sie dir die Arbeit abnimmt. Aber nur weil du das Problem nicht mehr siehst, heißt das nicht, dass es nicht prinzipiell da ist.
-
Über den Ansatz mit den Klammern hab ich auch schon nachgedacht. Hab ihn aber wieder verworfen, weil man ja auch noch Variablen gebrauchen könnte, die auf diesem Weg durch ihre Initialisierung in einen anderen Block rutschen.
-
Paul Müller schrieb:
Über den Ansatz mit den Klammern hab ich auch schon nachgedacht. Hab ihn aber wieder verworfen, weil man ja auch noch Variablen gebrauchen könnte, die auf diesem Weg durch ihre Initialisierung in einen anderen Block rutschen.
Was meinst du mit Variablen, die durch ihre Initialisierung in einen anderen Block rutschen?
@314159265358979 :
Natürlich ist der Ansatz ernst gemeint - scopes eingefügt, Objekte werden zerstört wenn sie nicht mehr gebraucht werden und dabei Resourcen freigegeben -> RAII umgesetzt.
-
{ std::ifstream is("exit.bin"); unsigned char tmp; is >> tmp; std::cout << std::hex << static_cast<unsigned>(tmp) << std::endl; } // is und tmp werden hiernach nie wieder gebraucht, also lokal machenWas ist, wenn ich tmp später doch noch brauche? Dann bleibt mir ja gar nichts anderes übrig, als tmp außerhalb des Scopes zu deklarieren. Und damit hätte ich ja kein RAII mehr. Auch wenn RAII in Verbindung mit tmp in jedem Fall verletzt wird, so beschränkt sich die Variante von SeppJ zumindest auf eine minimal mögliche Verletzung.
-
Paul Müller schrieb:
Was ist, wenn ich tmp später doch noch brauche? Dann bleibt mir ja gar nichts anderes übrig, als tmp außerhalb des Scopes zu deklarieren.
Genau.
Und damit hätte ich ja kein RAII mehr.
Wieso nicht?
Faustregel: RAII funktioniert und hilft immer. Gegenbeispiele musst du schon sehr gezielt konstruieren. Hier sehe ich nicht, was du für ein Problem haben könntest.
-
Ich seh den Zusammenhang nicht ganz. Inwiefern würde eine Definition (nicht Deklaration) von tmp im übergeordneten scope (also der main-Funktion) das RAII-Idiom verletzen?
Die STL macht gebrauch von der RAII-Technik - beim file-stream-template wird eben im Destruktor close() aufgerufen. Dann macht es allerdings wenig Sinn, wenn ich die Lebensdauer eines filestream-Objekts unnötig verlänger - im schlimmsten Fall leg ich es global an.
Also versucht man Objekte möglichst lokal zu halten und genau das geschieht hier doch.