streamreading (java to c++)
-
Ich möchte folgende Java-Funktion in C++ nachprogrammieren:
(stream ist ein InputStream)
protected long readLong() throws IOException { byte[] bytes = new byte[8]; this.stream.read(bytes); return ((long) (bytes[7] & 0xff) << 56) | ((long) (bytes[6] & 0xff) << 48) | ((long) (bytes[5] & 0xff) << 40) | ((long) (bytes[4] & 0xff) << 32) | ((long) (bytes[3] & 0xff) << 24) | ((long) (bytes[2] & 0xff) << 16) | ((long) (bytes[1] & 0xff) << 8) | (bytes[0] & 0xff); }meine vorläufige c++ variante sieht so aus, wobei stream ein ifstream ist:
long Test::readLong() { char* bytes = new char[8]; stream.read(bytes, 8); return ((long)(bytes[7] & 0xFF) << 56) | ((long)(bytes[6] & 0xFF) << 48) | ((long)(bytes[5] & 0xFF) << 40) | ((long)(bytes[4] & 0xFF) << 32) | ((long)(bytes[3] & 0xFF) << 24) | ((long)(bytes[2] & 0xFF) << 16) | ((long)(bytes[1] & 0xFF) << 8) | (bytes[0] & 0xFF); }Beim kompilieren bekomme ich nun aber diese Warnung:
"'<<' shift count negative or too big, undefined behaviour"Hat jemand eine Idee wie ich den Code richtig in C++ übersetzen kann?
Vielen Dank schon mal!
-
long ist bei dir wahrscheinlich nicht 64 bit breit. Nimm stattdessen int64_t.
char würde ich auch nicht nehmen, wenn du mit Bytes hantierst. Mach dir lieber einen typedef unsigned char byte;.
-
und statt
char* bytes = new char[8];char bytes[8];damit das ganze auch wieder gelöscht wird.
-
danke! int64_t müsste ich vermutlich selbst definieren, aber mit long long funktioniertes auch.
Bezüglich char: ich hatte eigentlich vor unsigned char zu verwenden, aber die read methode verlangt einen char als parameter. Könnte es dann mit unsigned nicht zu problemen kommen?
-
brotbernd schrieb:
und statt
char* bytes = new char[8];char bytes[8];damit das ganze auch wieder gelöscht wird.
diese variante wollte ich auch ursprünglich verwenden, hatte damit aber auch probleme mit der read methode, da ich dann diesen kompilierfehler bekam:
Error 1 error C2664: 'std::basic_istream<_Elem,_Traits>::read' : cannot convert parameter 1 from 'char (*)[4]' to 'char *'
also wenn ich bei meiner variante bleibe, müsste ich also noch ein delete bytes einfugen
-
int64_t & Co. bekommst du mit <stdint.h>.
Warum eine read-Funktion char* als Parameter erwartet ist mir zwar rätselhaft, aber du kannst ihr gefahrlos einen unsigned char-Zeiger geben. Der benötigte Cast ist natürlich nicht so schön.Edit:
Error 1 error C2664: 'std::basic_istream<_Elem,_Traits>::read' : cannot convert parameter 1 from 'char (*)[4]' to 'char *'Du hast char* bytes[8]; geschrieben.
Edit2:
Und auch dann müsste es delete[] bytes heißen.Wozu dienen eigentlich die ganzen &0xff? Das scheint mir weder in Java noch in C++ viel Sinn zu machen, denn größer als 0xff können Bytes sowieso nicht sein.
-
stdint.h kennt der compiler nicht (Visual Studio 2008).. also bleibe ich vorläufig einfach bei long long.
den cast habe ich nur mit reinterpret_cast hinbekommen, ich denke das wird in diesem fall schon ok sein.
die '& 0xFF' verstehe ich auch nicht. ich habe nur den java code vorliegen, den ich nun nach c++ überführen soll und so weit ich weiß funktioniert der java-code, also habe ich das einfach übernommen.
Edit:
vielleicht werden die 0xFF's in Java deswegen benötigt, da es in java keine unsigned bytes gibt und auf diese Weise das Vorzeichen beseitigt wird?
-
Im Prinzip ist es vollkommen wurst, ob
charoderunsigned char, die ham ja eh dieselbe Bitrepräsentation und da ja hier nur mit Bits gearbeitet wird, kann man beides nehmen.
-
ich hätte hier noch ein weiteres Problem: und zwar muss ich UTF-8 codierte String einlesen.
protected String readString(int size, int len, String charset) throws IOException { int length = (size > 0 ? size : len); byte[] bytes = new byte[length]; this.stream.read(bytes); length = (len >= 0 ? len : size); try { return new String(new String(bytes, 0, length, charset).getBytes("UTF-8"), "UTF-8"); } catch(Throwable e) { e.printStackTrace(); } return new String(bytes, 0, length); }hat jemand eine Idee wie ich den Code ab dem try in C++ nachprogrammiere?
Zur Zeit sieht der Code so aus, ich komme leider nur bis zum einlesen der Daten. Wie kann ich den char* in einen UTF-8 string casten bzw. welcher Datentyp ist dafür in c++ vorgesehen? So weit ich weiß ist ein wchar_t ja ein 16-bit Unicode, ein char* zwar 8-bit aber wieder ASCII codiert.
??? Test::readString(int size, int len) { int length = (size > 0 ? size : len); unsigned char* bytes = new unsigned char[length]; stream.read(reinterpret_cast<char*>(bytes), length); }Ich hoffe jemand kennt sich damit aus, und auch vielen Dank für die bisherigen Beiträge!