Forum: Mikrocontroller und Digitale Elektronik dumme Frage zu printf ()


von H.Joachim S. (crazyhorse)


Lesenswert?

#define START 0x02

printf ("\x02%02x:%u:%u\r",adr,data,crc);

mit \x02 funktioniert das ja problemlos. Es wird aber verschiedene 
Varianten geben mit verschiedenen Kennungen für das erste Byte und da 
möchte ich natürlich nicht jedesmal alle Ausgaben ändern. Gibts ne 
Möglichkeit, START einzufügen?

Im Moment mache ich es so:
putchar (START);
printf ("%02x:%u:%u\r",adr,data,crc);

Ist im Prinzip in Ordnung, hätte es trotzdem gerne direkt in printf().

von Peter II (Gast)


Lesenswert?

H.Joachim S. schrieb:
> Ist im Prinzip in Ordnung, hätte es trotzdem gerne direkt in printf().

dann mach es doch einfach
1
printf ("%c%02x:%u:%u\r", 0x2, adr,data,crc);

von H.Joachim S. (crazyhorse)


Lesenswert?

Hm, das behandelt das Startbyte aber als Variable mit entsprechend mehr 
(unnötigem) Code. Gerade mal probiert, pro printf() macht das 16 Byte. 
Compiler scheint das nicht zu optimieren.
Na gut, dann lass ich es bei der putchar()-Variante.

von Peter II (Gast)


Lesenswert?

teste mal mit
1
#define START 0x02
2
printf ("\x" START "%02x:%u:%u\r",adr,data,crc);

von Pandur S. (jetztnicht)


Lesenswert?

Schluck ... die eierlegende Wollmilchsau "printf", um ein paar Bytes 
zusammenzukleben ...
 dazu verwendet man ein Array und fuellt die Werte per Zuweisung ein.

von H.Joachim S. (crazyhorse)


Lesenswert?

error
invalid hexadecimal number

von Peter II (Gast)


Lesenswert?

Oh D. schrieb:
> Schluck ... die eierlegende Wollmilchsau "printf", um ein paar Bytes
> zusammenzukleben ...
>  dazu verwendet man ein Array und fuellt die Werte per Zuweisung ein.

dazu braucht er aber auch noch itoa.

von Stefan F. (Gast)


Lesenswert?

> die eierlegende Wollmilchsau "printf"

Ist halt so schön praktisch. Aber jedes mal, wenn mein Programm nicht 
mehr in den Flash passt, sind dass die Stellen, die ich als erstes 
optimiere.

von H.Joachim S. (crazyhorse)


Lesenswert?

Man kann über printf prächtig streiten...
Man kann es benutzen (ich tue es, weil es bequem ist), muss es aber 
nicht.
Und wenn der MC mal droht voll zu werden, hat man noch Potential. Für 
ungenutzten flash bekomme ich nichts.

von Amateur (Gast)


Lesenswert?

@Joachim
>Gerade mal probiert, pro printf() macht das 16 Byte.
>Compiler scheint das nicht zu optimieren.
Du bindest ein riesen Trumm von Funktion ein (die eierlegende 
Wollmichsau braucht sehr viel Platz) und störst Dich an ein paar 
zusätzlichen Bytes?

von Peter II (Gast)


Lesenswert?

H.Joachim S. schrieb:
> pro printf() macht das 16 Byte.

schon merkwürdig, hast du mal ins ASM geschaut warum es so viel mehr 
ist?

es ist ja nur ein wert mehr auf den Stack also 2 Byte.

von H.Joachim S. (crazyhorse)


Lesenswert?

Amateur schrieb:
> @Joachim
>>Gerade mal probiert, pro printf() macht das 16 Byte.
>>Compiler scheint das nicht zu optimieren.
> Du bindest ein riesen Trumm von Funktion ein (die eierlegende
> Wollmichsau braucht sehr viel Platz) und störst Dich an ein paar
> zusätzlichen Bytes?

Ja :-)
Es gibt ja nicht nur die eine (hier beispielhafte) Ausgabefunktion, 
sondern etliche (im Moment 17). Daten, Statusmeldungen, Fehlermeldungen 
etc.
Allen gemeinsam ist, dass sie alle mit einem Steuerzeichen beginnen. Und 
das soll je nach Einstellung eben ein anderes sein, sozusagen eine 
variable Konstante :-).

Es wäre schön, wenn sich die Diskussion ab jetzt auf die eigentliche 
Frage beziehen würde.
Wenn es sich nicht per #define machen lässt ist es auch in Ordnung, dann 
lass ich eben putchar.

von Mikro 7. (mikro77)


Lesenswert?

H.Joachim S. schrieb:
> Ist im Prinzip in Ordnung, hätte es trotzdem gerne direkt in printf().

Spricht was gegen...
1
#include <stdio.h>
2
3
#define START "\x02"
4
5
int main()
6
{
7
  printf(START "%d",42) ;
8
  return 0 ;
9
}
1
prompt> ./test | od -c
2
0000000 002   4   2
3
0000003

Edit: Das geht natürlich nicht mit "\x00".

von H.Joachim S. (crazyhorse)


Lesenswert?

Dann gibts (zumindest bei CodeVision) gar keine Ausgabe mehr.
Na gut, Danke für die Mühe. Ich lass es jetzt wie gehabt.

von Volker B. (Firma: L-E-A) (vobs)


Lesenswert?

Peter II schrieb:
> teste mal mit
>
1
> #define START 0x02
2
> printf ("\x" START "%02x:%u:%u\r",adr,data,crc);
3
>

Wohl eher so:
1
  #define START "0x02"
2
  printf (START "%02x:%u:%u\r",adr,data,crc);
oder so:
1
  #define START "02"
2
  printf ("0x" START "%02x:%u:%u\r",adr,data,crc);


Grüßle,
Volker.

von H.Joachim S. (crazyhorse)


Lesenswert?

funktioniert beides nicht, aber so:

#define START "\x03"
printf (START"%02....

Und jetzt sehe ich, dass das exakt die Lösung von Mikro77 ist :-(
Was habe ich da bloss falsch getippselt?

Und was dabei gelernt - bis jetzt wusste ich nicht, dass man einfach 
mehrere Formatstrings nehmen kann.

von Volker B. (Firma: L-E-A) (vobs)


Lesenswert?

H.Joachim S. schrieb:
> funktioniert beides nicht, aber so:

Uralter Compiler? GCC 4.8.2 "frisst" meine Codeschnipsel ohne Murren und 
erzeugt sogar das gewünschte Ergebnis. Vielleicht wären weitere 
Informationen hilfreich...

Grüßle,
Volker.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Volker B. schrieb:
> Peter II schrieb:
>> teste mal mit
>>> #define START 0x02
>> printf ("\x" START "%02x:%u:%u\r",adr,data,crc);
>>
> Wohl eher so:  #define START "0x02"
>   printf (START "%02x:%u:%u\r",adr,data,crc);
>   oder so:  #define START "02"
>   printf ("0x" START "%02x:%u:%u\r",adr,data,crc);

Volker B. schrieb:

> Uralter Compiler? GCC 4.8.2 "frisst" meine Codeschnipsel ohne Murren und
> erzeugt sogar das gewünschte Ergebnis.

Ach? Ziemlich frech formuliert, denn:

Dein 1. Vorschlag:

> #define START "0x02"
>   printf (START "%02x:%u:%u\r",adr,data,crc);

wird vom Compiler so zusammengebaut:

>   printf ("0x02%02x:%u:%u\r",adr,data,crc);

D.h. es wird der String "0x02" am Anfang ausgegeben. Es war aber ein 
einzelnes Startzeichen gefordert, dass dem Hex-Wert 0x02 enstpricht.

Dein 2. Vorschlag:

>   #define START "02"
>   printf ("0x" START "%02x:%u:%u\r",adr,data,crc);

wird ebenso vom Compiler so zusammengebaut:

>   printf ("0x02%02x:%u:%u\r",adr,data,crc);

Und hat natürlich auch nicht den gewünschten Effekt. Der String "0x02" 
ist nicht gewünscht.

Bitte genauer lesen, bevor man alles auf die Compilerversion schiebt und 
damit die Diskussion in eine vollkommen falsche Richtung lenkt.

von H.Joachim S. (crazyhorse)


Lesenswert?

Wie schon gesagt, CodeVision.
Nach deinem Code liefert die Ausgabe
0x03....
also die 0x03 tatsächlich als 4 Byte Ascii. Und das scheint mir auch 
sehr logisch so.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

H.Joachim S. schrieb:
> Und was dabei gelernt - bis jetzt wusste ich nicht, dass man einfach
> mehrere Formatstrings nehmen kann.

Seit C89.  Nur so lässt sich nämlich das Problem lösen, dass das
syntaktische Ende einer \x-Escapefolge nicht nach irgendeiner Anzahl
von N weiteren Zeichen ist, sondern erst mit dem ersten Zeichen,
welches nicht mehr hexadezimal ist.  Sowas:

"\x0D\x0AAlles im Eimer\0x0D0x0A"

würde nämlich nicht "<CR><NL>Alles im Eimer<CR><NL>" ausgeben,
sondern "<CR>ªlles im Eimer<CR><NL>" (mal in der Annahme von
ISO8859-1).  Schreibt man es als:

"\x0D\x0A" "Alles im Eimer\x0D\x0A"

funktioniert es.

Bei den historisch älteren Oktalzahlen war es noch so, dass diese
automatisch auf maximal drei Oktalziffern limitiert waren, aber mit
C89 sollte auch die Möglichkeit für andere Zeichensätze als solche
mit nur 8 Bit geschaffen werden, daher kein „automatisches“ Ende
eines hexadezimal angegebenen Zeichens.

von Volker B. (Firma: L-E-A) (vobs)


Lesenswert?

Frank M. schrieb:

> Dein 1. Vorschlag:
>
>> #define START "0x02"
>>   printf (START "%02x:%u:%u\r",adr,data,crc);
>
> wird vom Compiler so zusammengebaut:
>
>>   printf ("0x02%02x:%u:%u\r",adr,data,crc);
>
> D.h. es wird der String "0x02" am Anfang ausgegeben. Es war aber ein
> einzelnes Startzeichen gefordert, dass dem Hex-Wert 0x02 enstpricht.
>

Danke für Deine erhellenden Worte! Ich hatte die ausführliche Antwort 
des Fragestellers "funktioniert beides nicht" als Hinweis auf eine 
Compiler-Fehlermeldung gedeutet.

Grüßle,
Volker.

von H.Joachim S. (crazyhorse)


Lesenswert?

@Jörg: Danke, sehr schön und schlüssig erklärt.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.