PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Verständnisproblem Variable auf Display ausgeben



wkrug
23.10.2017, 22:45
Hallo,

Ich hab mir kürzlich AVR Studio 7 auf meinen Rechner gespielt und eine XMEGA library für ein OLED Display mit SSD1309 Chip für den AVR umgebastelt.
Es funktioniert auch alles so weit.

Ich hab da aber jetzt ein Verständnisproblem mit den folgenden Programmzeilen:

for (percent=0; percent<=100; percent++)
{
ssd1309_drawBargraph((uint8_t)percent, 0, 7, 0, 15);
ssd1309_drawBargraph((uint8_t)percent, 6, 7, 30, 98);
ssd1309_printf_P(1, 20, PSTR("Level: %3d %%"), percent);
_delay_ms(100);
}
Es geht dabei um die Programmzeile:

ssd1309_printf_P(1, 20, PSTR("Level: %3d %%"), percent);
Auf dem Display wird z.B. | Level: 12 % | ausgegeben. Wobei 12 dem aktuellen Wert von percent darstellt, der hochgezählt wird.

Die zugehörige Funktion schau so aus:

void ssd1309_printf_P(uint8_t page, uint8_t startColumn, PGM_P __fmt, ...)
{
char aString[64];
va_list argumentlist;
va_start(argumentlist, __fmt);
vsprintf_P(aString, __fmt, argumentlist);
va_end(argumentlist);
ssd1309_print(aString, page, startColumn);
}

Wie wird aus percent plötzlich ein ASCII Code?
Was bedeutet der Teil %3d ?
Was bedeutet %% ?

Ceos
24.10.2017, 07:06
printf steht für print formated
referenz zum detaillierten nachlesen http://www.cplusplus.com/reference/cstdio/printf/
zusammengefasst, der string in printf wird interpretiert, "%" steht dabei als sog. escape-char ... wann immer du % schreibst, signalisierst du dem printf, danach folgt eine definierte zeichenkette die du interpretieren musst um die darstellung zu ermitteln

deswegen steht da %3d:
- % beginn der interpretation
- 3d in dem kontext bedeutet das "d" dezimal, also interpretiere eine später genannte variable als dezimalzahl und die 3 davor sagt, dass er dafür 3 ziffern verwenden soll

nach dem formatierungsstring in printf kommen dann die variablen die interpretiert werden sollen. Also sollten idealerweise für jede variablen interpretation im format string auhc eine variable danach folgen sonst knallts :D

da du das zeichen "%" als escape-char verwendest, es jetzt aber als zeichen ausgeben möchtest, machst du schlicht "%%" das erste zeichen sagt escape sequenz udn das zeichen danach wird dann einfach ausgegeben

wkrug
24.10.2017, 16:47
Hi,
danke für die gut erklärte Antwort.
Jetzt ist mir klar was da passiert.

Der Link ist auch gut und verständlich.

Die meisten Referenzen die man so findet bestehen aus einem Mischung aus Parametern und frei definierbaren Variablen.
Man kann da oft nicht erkennen, was welcher Buchstabe denn nun was sein soll.

Jetzt muß ich nur noch die Geschichte mit der va_list verstehen.

Ceos
24.10.2017, 17:15
Man kann da oft nicht erkennen, was welcher Buchstabe denn nun was sein soll

alles eine frage der übung, aber die reihenfolge der variablen (man kann mehr als eine verwenden) sollte dann auch mit der position im text übereinstimmen, wie gesagt sonst machst bumm :D

HaWe
24.10.2017, 17:41
das mit der va_list hängt mit vsprintf zusammen:
http://www.cplusplus.com/reference/cstdio/vsprintf/?kw=vsprintf
das ist zwar wirklich nichts für Anfänger, dennoch kann man es mit Mühe und Aufwand schon verstehen.
Sie steht für die Liste der durch Kommata getrennten Variablen, die auf den FormatString folgen, von nicht festgelegter Länge, also wie bei

printf( FormatString, ... )
// oder auch geschrieben als
printf( FormatString, va_list );

Beispiel:
printf("die ersten vier natürlichen Zahlen heißen %d, %d, %d, %d! ", 1,2,3,4);
1,2,3,4 sind die Elemente der va_list, symbolisiert durch die Punkte ...

ps,
ein gutes Beispiel zu va_list und va_arg findest du auch hier:
http://www.cplusplus.com/reference/cstdarg/va_arg/

wkrug
25.10.2017, 13:02
printf("die ersten vier natürlichen Zahlen heißen %d, %d, %d, %d! ", 1,2,3,4);
1,2,3,4 sind die Elemente der va_list, symbolisiert durch die Punkte ...

Danke, nun ist mir das etwas klarer.
Ich hab bisher solche Strings mit strcat in einem String zusammengefügt.
Die Möglichkeit hier scheint aber auch gut zu sein.

HaWe
25.10.2017, 20:59
die va_list macht eigtl nur Sinn wenn man Funktionen braucht, die ständig eine wechselnde Anzahl von Parametern haben und dadurch universell verwendbar sein müssen.