Ich versuche den Inhalt der PNG-Datei zu lesen.
Wie Sie vielleicht wissen, werden alle Daten in 4-Byte-Form in PNG-Dateien geschrieben, sowohl in Text als auch in Zahlen. Wenn wir die Nummer 35234 haben, ist es auf diese Weise sicher: [1000] [1001] [1010] [0010].
aber manchmal sind die Zahlen kürzer, also sind die ersten Bytes Null, und wenn ich das Array lese und es von char * in eine Ganzzahl umwandle, bekomme ich eine falsche Nummer. zum Beispiel [0000] [0000] [0001] [1011] manchmal werden Zahlen als negative Zahlen und gleichzeitig als null fehlinterpretiert!
lassen Sie mich Ihnen ein intuitives Beispiel geben:
%Vor%Ich wünschte, ich könnte mein Problem gut erklären!
Wie kann ich solche Arrays in einen ganzzahligen Wert umwandeln?
ok ok ok, lass mich meinen Code ändern, um es besser zu erklären:
%Vor%hier müssen wir 13 als Ergebnis bekommen, ok? Aber mit dieser neuen Lösung ist die Antwort falsch, du kannst sie auf deinen Computern testen! Ich bekomme diese Nummer: 218103808 was definitiv falsch ist!
Sie übergeben (char *) an (int). Was Sie tun sollten, ist den Zeiger auf den Integer, d. H.
%Vor%Aber wirklich sollten Sie Ihren Code in seine eigene Funktion extrahieren und sicherstellen, dass:
sizeof(int) == 4
static, dynamic, const, reinterpret
) Wenn Sie eine Little-Endian-Maschine mit einer 32-Bit-Ganzzahl annehmen, können Sie Folgendes tun:
%Vor%Um es in Schritte zu brechen:
s_num
ist ein Array, das als Zeiger auf sein erstes Element interpretiert werden kann ( char*
hier) s_num
bis int*
wegen (1) - es ist in Ordnung, Zeiger zu werfen Damit 0xAF
das niederwertige Byte der Ganzzahl ist. Voller Beispiel (C-Code):
Drucke:
%Vor%Wie erwartet.
Beachten Sie, dass diese Methode nicht zu portierbar ist, da sie Endianess und Integer-Größe voraussetzt. Wenn Sie eine einfache Aufgabe auf einer einzelnen Maschine ausführen müssen, können Sie damit durchkommen, aber für eine Produktionsqualität müssen Sie die Portabilität berücksichtigen.
Auch in C ++ - Code wäre es besser, reinterpret_cast
anstelle der C-Stil-Umwandlung zu verwenden.
Ich finde die Verwendung des STD-Bitsets die explizitste Art der Konvertierung (insbesondere Debugging).
Das Folgende ist vielleicht nicht das, was Sie in Ihrem endgültigen Code haben wollen (vielleicht zu ausführlich) - aber ich finde es großartig, wenn Sie versuchen, genau zu verstehen, was vor sich geht.
%Vor%Axels Antwort verstößt gegen das strenge Aliasing-Regel , mindestens seit C ++ 14. Also poste ich diese Antwort für zukünftige Benutzer.
Abgesehen von Endian- und Größenproblemen ist die Verwendung von std::memcpy
eine sichere Methode. dh
EDIT: Es scheint, dass Sie die Zahlen nicht summieren wollen. Diese Antwort hier für die Nachwelt zu hinterlassen, beantwortet aber wahrscheinlich nicht die Frage, die Sie stellen möchten.
Sie möchten die Werte zusammenfassen, verwenden Sie also std::accumulate
:
Erzeugt Ausgabe:
%Vor%Wussten Sie, dass Int in C ++ nach dem 32767-ten Wert übergelaufen ist? Das würde deine negative Zahl für 35234 erklären.
Die Lösung besteht darin, einen Datentyp zu verwenden, der die größeren Werte verarbeiten kann. Weitere Informationen finden Sie im Artikel "Integer-Überlauf":
UPDATE : Ich habe das geschrieben und nicht gedacht, dass wir alle in der modernen Welt leben, in der 32-Bit- und 64-Bit-Maschinen existieren und gedeihen !! Der Überlauf für int ist in der Tat viel viel größer als meine ursprüngliche Aussage.