Hallo, folgende Zeile Code habe ich irgendwo gefunden (ist jetzt egal woher): unsigned char buf[20]; scanf("%X %X %X", (unsigned int*)buf, (unsigned int*)buf+1, (unsigned int*)buf+2); Sinn des Ganzen ist dass eine Zeile der Form "01 23 AB" von Hexziffern eingelesen werden soll wobei zwei Hexziffern ein Byte darstellen sollen. Es funktioniert nicht und man macht sowas auch nicht unbedingt. Nur verstehe ich das Ergebnis nicht ganz, im Speicher steht dann buf[0] = FF buf[1] = 0 buf[2] = 0 Ich könnt's mir eigentlich nur erklären wenn man davon ausgeht dass scanf() die Werte von rechts nach links füllt (und das Ganze auf einer Little-Endian-Maschine läuft, was ja bei IA32 der Fall ist). Wie gesagt: Mir geht's nicht darum wie ich den Code stattdessen schreiben soll, dass er funktioniert sondern nur um die Erklärung des Ergebnisses. Gruß, Bernhard -- _________ http://www.bwalle.de _________________________________________________ Q: How does a Unix guru have sex? A: unzip;strip;touch;finger;mount;fsck;more;yes;umount;sleep
Hi
folgende Zeile Code habe ich irgendwo gefunden (ist jetzt egal woher):
Wann sag ich das noch mal immer... (-;
unsigned char buf[20]; scanf("%X %X %X", (unsigned int*)buf, (unsigned int*)buf+1, (unsigned int*)buf+2);
Sinn des Ganzen ist dass eine Zeile der Form "01 23 AB" von Hexziffern eingelesen werden soll wobei zwei Hexziffern ein Byte darstellen sollen.
Es funktioniert nicht und man macht sowas auch nicht unbedingt. Nur verstehe ich das Ergebnis nicht ganz, im Speicher steht dann
buf[0] = FF buf[1] = 0 buf[2] = 0
Ich könnt's mir eigentlich nur erklären wenn man davon ausgeht dass scanf() die Werte von rechts nach links füllt (und das Ganze auf einer Little-Endian-Maschine läuft, was ja bei IA32 der Fall ist).
Mir scheint, Du bist Dir etwas uneins. Du hast zwar ein Array of char, liesst darin aber ints ein. Bei mir kommt durchaus das, was ich erwarten wuerde. Bei Ausgabe mittels: for ( i = 0; i < 20; i++ ) { printf( "%d ", buf[i] ); } bekomme ich plausible Werte: 1 0 0 0 35 0 0 0 171 0 0 0 0 1 0 0 1 0 0 0 Bye P.S: Woher weisst printf eigentlich, ob ich ein char, int oder sonstwas uebergebe? Also woher weiss es, dass es fuer die Darstellung nur auf ein Byte zugreifen muss, wo doch %d auch fuer ints verwendbar ist? -- 1 Bodo Kaelberer 123 http://www.webkind.de/ 3 4 Politik ist, wenn viele sich streiten und keiner sich freut.
* Bodo Kaelberer
P.S: Woher weisst printf eigentlich, ob ich ein char, int oder sonstwas uebergebe? Also woher weiss es, dass es fuer die Darstellung nur auf ein Byte zugreifen muss, wo doch %d auch fuer ints verwendbar ist?
Gar nicht. printf() bekommt keinen Zeiger sondern einen Wert. char wird einfach vor der Übergabe auf int erweitert. Gruß, Bernhard -- _________ http://www.bwalle.de _________________________________________________ Die Freiheit des Menschen liegt nicht darin, dass er tun kann, was er will, sondern dass er nicht tun muss, was er nicht will. -- Jean-Jacques Rousseau
* Bernhard Walle
* Bodo Kaelberer
[2004-01-16 16:33]: P.S: Woher weisst printf eigentlich, ob ich ein char, int oder sonstwas uebergebe? Also woher weiss es, dass es fuer die Darstellung nur auf ein Byte zugreifen muss, wo doch %d auch fuer ints verwendbar ist?
Gar nicht. printf() bekommt keinen Zeiger sondern einen Wert. char wird einfach vor der Übergabe auf int erweitert.
ich glaube ganz so einfach ist es doch nicht. Richtig sollte man %hd (short) oder %hhd (char) angeben. Was sagen die Experten? Gruß, Bernhard -- _________ http://www.bwalle.de _________________________________________________ Faulheit ist die Angewohnheit, sich auszuruhen, bevor man müde ist. -- (unbekannt)
Bernhard Walle schrieb:
* Bernhard Walle
[2004-01-16 17:07]: * Bodo Kaelberer
[2004-01-16 16:33]: P.S: Woher weisst printf eigentlich, ob ich ein char, int oder sonstwas uebergebe? Also woher weiss es, dass es fuer die Darstellung nur auf ein Byte zugreifen muss, wo doch %d auch fuer ints verwendbar ist?
printf weiß es nicht. printf nimmt int an, da %d im Formatstring übergeben wurde.
Gar nicht. printf() bekommt keinen Zeiger sondern einen Wert. char wird einfach vor der Übergabe auf int erweitert.
Ja, s.u.
ich glaube ganz so einfach ist es doch nicht. Richtig sollte man %hd (short) oder %hhd (char) angeben.
Was sagen die Experten?
Bin zwar kein Experte, werde mich aber trotzdem mal dran versuchen... Falls die Adressgröße des Stack-Segmentes 32Bit ist, landen die Parameter, die an printf übergeben werden immer an 32Bit-Grenzen. Falls der Datentyp kleiner 32Bit ist, macht dies nichts aus, da die höherwertigen Bytes beim pushen auf den Stack auf Null gesetzt werden. Dies gilt auch für char. Auf dem Stack liegt damit sozusagen (int)buf[i], das %d funktioniert. -- Gruß, Alex
Hi, On Fri, 16 Jan 2004, Bernhard Walle wrote:
ich glaube ganz so einfach ist es doch nicht. Richtig sollte man %hd (short) oder %hhd (char) angeben.
printf() ist eine variadic function. D.h. das _alle_ Argument nach dem Formatstring den default promotions unterworfen sind. U.a. heisst dies, dass 'char' und 'short' bei Uebergabe an printf() implizit nach 'int' umgewandelt werden. Damit ist '%d' (oder %u) also immer passend fuer chars und shorts. Der Modifikator 'h' oder 'hh' fuehrt nur dazu, dass das 'int' Argument vor Ausgabe wieder nach 'short' oder 'char' gecastet wird. An der Semantik aendern beide Modifikatoren also nichts, sie wuerden also nur der Codedokumentation dienen. Wie ich gerade sehe ist 'hh' nicht mal ganz richtig implementiert, da '%hhd' auf 1024 angewendet immer noch 1024 ausgibt (und nicht das auf char gecastete, i.e. 0).
Was sagen die Experten?
Man vergesse dass es 'h' und 'hh' gibt, waere glaube ich ein vernuenftiger Rat. Ciao, Micha.
* Bernhard Walle
Hallo,
folgende Zeile Code habe ich irgendwo gefunden (ist jetzt egal woher):
unsigned char buf[20]; scanf("%X %X %X", (unsigned int*)buf, (unsigned int*)buf+1, (unsigned int*)buf+2);
Sinn des Ganzen ist dass eine Zeile der Form "01 23 AB" von Hexziffern eingelesen werden soll wobei zwei Hexziffern ein Byte darstellen sollen.
Es funktioniert nicht und man macht sowas auch nicht unbedingt. Nur verstehe ich das Ergebnis nicht ganz, im Speicher steht dann
buf[0] = FF buf[1] = 0 buf[2] = 0
Ich könnt's mir eigentlich nur erklären wenn man davon ausgeht dass scanf() die Werte von rechts nach links füllt (und das Ganze auf einer Little-Endian-Maschine läuft, was ja bei IA32 der Fall ist).
Blöder Denkfehler: Ich habe (unsigned int*)buf + 1 mit (unsigned int*)(buf + 1) verwechselt. Jetzt ist es klar. Gruß, Bernhard -- _________ http://www.bwalle.de _________________________________________________ "Damn the torpedoes. Full speed ahead" -- Capt. David Farragut
participants (4)
-
Alexander Veit
-
Bernhard Walle
-
Bodo Kaelberer
-
Michael Matz