Hex-Werte konvertieren
-
Hallo,
ich lese zum beispiel folgende werte aus einer datei aus:
0020 (zahl ist hexadezimal)
diese möchte ich jetzt zu einem int konvertieren.
jetzt sind jedoch die nullen, glaube ich zumindest, ein problem.
wenn ich so die zahl umwandele, gibt es keine probleme, was ja auch klar ist, weil die nullen "richtige sind" und keine escape sequenz:stringstream ss("0020"); int i; ss << hex; ss >> i; // i = 32wenn ich jedoch versuche, die ziffern aus der datei auszulesen, und dann versuche umzuwandeln, klappt es nicht. i bleibt un initialisiert:
int to_dec(const std::vector<char>& s) // vector mit inhalt '\0' '\0' '\20' { int i; std::stringstream ss; for (auto it = s.begin(); it != s.end(); ++it) { ss << *it; } ss << std::hex; ss >> i; return i; }danke schonmal
gast_1
-
Die Zahlen bei Characters nach dem \ sind afaik oktal angegeben.
\0 \0 \20 ist also 0016.int to_dec(const std::vector<char>& s) // vector mit inhalt '\x00' '\x00' '\x20' { int i; std::stringstream ss; for (auto it = s.begin(); it != s.end(); ++it) ss << static_cast<int>(*it); // ss == 0032 ss >> i; return i; } int main () { vector<char> vec; vec.push_back('\x00'); vec.push_back('\x00'); vec.push_back('\x20'); int i = to_dec(vec); cout << i << endl; return 0; }Ich bin mir nicht sicher, ob ich dich richtig verstanden habe.
Wie sieht der Inhalt der Datei aus?
-
so sieht der anfang der datei aus (aus hex-editor kopiert) und es geht um die letzten 4 byte.
BLENDER-v258REND42 4c 45 4e 44 45 52 2d 76 32 35 38 52 45 4e 44 20 00 00 00was mich gerade etwas verwirrt ist dass die datei eigentlich little endian ist, aber dann müsste doch eigentlich die letzten 4 byte 00 00 00 20 heißen, wenn das ein integer sein sollte, oder? wenn ich das ganze in meinem programm einlese, ist die reihenfolge der bytes wie von mir beschrieben und nicht so, wie sie vom hex-editor angezeigt wird.
-
verdammt denkfehler von mir. das mit der byte reihenfolge passt schon, aber trotzdem wird es bei mir genau andersherum eingelesen.
-
gast_1 schrieb:
stringstream ss("0020");int to_dec(const std::vector<char>& s) // vector mit inhalt '\0' '\0' '\20'Wie kommst du eigentlich darauf, dass
'0' == '\0'?
Was willst du mit dem ganzen bezwecken?
-
gast_1 schrieb:
so sieht der anfang der datei aus (aus hex-editor kopiert) und es geht um die letzten 4 byte.
BLENDER-v258REND42 4c 45 4e 44 45 52 2d 76 32 35 38 52 45 4e 44 20 00 00 00was mich gerade etwas verwirrt ist dass die datei eigentlich little endian ist, aber dann müsste doch eigentlich die letzten 4 byte 00 00 00 20 heißen, wenn das ein integer sein sollte, oder? wenn ich das ganze in meinem programm einlese, ist die reihenfolge der bytes wie von mir beschrieben und nicht so, wie sie vom hex-editor angezeigt wird.
Also auf Deutsch: Du möchtest die Binärdatei parsen.
Das ist die Lösung (verstehen musst du sie selber):
//zeigt auf die passende Stelle im Inhalt der Datei, //es folgen mindestens 4 Bytes (prüfe das!) const char *ptrToIntegerInFile = ...; std::uint32_t integer; std::memcpy(&integer, ptrToIntegerInFile, sizeof(integer));
-
TyRoXx schrieb:
Wie kommst du eigentlich darauf, dass
'0' == '\0'?
Was willst du mit dem ganzen bezwecken?da hab ich mich dann nur falsch ausgedrückt. mir ist schon klar, dass beides völlig andere sachen sin.
und danke auch für dein beispiel. dazu eine frage und zwar wie bekommt man einen zeiger auf die datei? soweit ich jetzt gerade gelesen hab bekommt man via std::basic_ifstream::rdbuf einen zeiger auf einen filebuf. aber wie kommt man mit diesem, wenn es mit dem überhaupt geht, direkten zugriff auf die datei?
-
gast_1 schrieb:
und danke auch für dein beispiel. dazu eine frage und zwar wie bekommt man einen zeiger auf die datei? soweit ich jetzt gerade gelesen hab bekommt man via std::basic_ifstream::rdbuf einen zeiger auf einen filebuf. aber wie kommt man mit diesem, wenn es mit dem überhaupt geht, direkten zugriff auf die datei?
Man kann die Datei ganz einfach in einen
vectoreinlesen und damit arbeiten.#include <fstream> #include <vector> #include <cstring> #include <string> #include <algorithm> #include <cstdint> const std::string FileBeginMagic = "BLENDER-v258REND"; std::vector<char> readFile(const std::string &name) { std::ifstream file(name); return std::vector<char>( std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>()); } int main() { const std::vector<char> content = readFile("Dateiname"); if (content.size() < FileBeginMagic.size()) { //Anfang fehlt return 1; } if (!std::equal(FileBeginMagic.begin(), FileBeginMagic.end(), content.begin())) { //Anfang falsch return 1; } const char * const integerPos = &content[0] + FileBeginMagic.size(); const char * const fileEnd = &content[0] + content.size(); std::uint32_t integer; if (integerPos + sizeof(integer) > fileEnd) { //es sind weniger als 4 Bytes nach dem Anfang vorhanden return 1; } //die Zahl kopieren std::memcpy(&integer, integerPos, sizeof(integer)); //so geht es weiter const char * const afterTheInteger = integerPos + sizeof(integer); //... }
-
wow danke nochmal. so ähnlich hab ich das jetzt auch gelöst.
aber noch was anderes. interpretiert der computer 20 00 00 00 als oktalzahl? weil wenn das hexadezimal wäre, wäre das 32 im dezimalsystem, aber es kommt 16 dez raus. meine quellen sagen mir, dass da aber 32 dez. herauskommen muss.
-
gast_1 schrieb:
wow danke nochmal. so ähnlich hab ich das jetzt auch gelöst.
aber noch was anderes. interpretiert der computer 20 00 00 00 als oktalzahl? weil wenn das hexadezimal wäre, wäre das 32 im dezimalsystem, aber es kommt 16 dez raus. meine quellen sagen mir, dass da aber 32 dez. herauskommen muss.Der Computer interpretiert da gar nichts.
Rate mal, in welchem Zahlensystem dein "Hex"-Editor die Zahlen anzeigt.
Wo kommt 16 raus?
-
das ist schon klar.
den wert 16 hat uint32_t nach dem memcpy.