Forum: Compiler & IDEs va_list an vsprintf() weiterreichen


von Oleg R. (m_bedded)


Lesenswert?

Hallo zusammen,

folgende Herausforderung. Man möchte eine va_list-Konstante festlegen 
und an vsprintf() weitergeben.
1
int8u_t X = 222;
2
int16u_t Y = 333;
3
4
va_list myarglist[] = {&X, &Y};
5
6
char mystring[10];
7
8
void myprint (char *s, va_list l)
9
{
10
  vsprintf(s, "%d %d", l);
11
}
12
13
void main (void)
14
{
15
  myprint(mystring, myarglist);
16
}

Ratet mal, was wird geprintet? Genau, die Adressen von X und Y, nicht 
die Werte. Wie kann ich dem Compiler erklären, was ich möchte?

Das Endziel wäre auch, myarglist[] ins Flash zu verschieben (WinAVR und 
mega128).

von Hannes J. (Firma: _⌨_) (pnuebergang)


Lesenswert?

va_list ist nicht dafür gedacht und nicht dafür geeignet. Die hinter 
va_list stehende Datenstruktur muss keine Liste sein und ist 
Compiler-spezifisch.

Hinzu kommt in dem Beispiel noch, dass %d für die Ausgabe eines 8 und 
eines 16 bit Wertes verwendet werden soll, ohne dass der Compiler die 
Chance für die übliche Integral-Promotion hat. Weiter sollen das wohl 
unsigned-Datentypen sein, für die %d sowieso der falsche 
Format-Specifier ist.
1
#include <inttypes.h> 
2
3
typdefe struct {
4
   uint8_t x;
5
   uint16_t y;
6
} Data;
7
8
Data data = { 222, 333 };
9
10
void myprint (char *s, Data *l)
11
{
12
   sprintf(s, "%"PRIu8 " %"PRIu16, l->x, l->y);
13
}

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Hi, bei mir sieht's so aus. Allerdings verwende ich selbstgeschriebene 
Ausgabefunktionen, weil printf-Zeug mir zu teuer ist oder nicht kann was 
ich brauche:
1
#include <stdarg.h>
2
3
// Decode format string <fmt> and dispatch to respective putter
4
5
static void
6
put_va (const char * fmt, va_list args)
7
{
8
    put_local = put_char;
9
10
    while (1)
11
    {
12
        char c = pgm_read_byte (fmt++);
13
14
        if ('\0' == c)
15
            return;
16
17
        if ('%' == c)
18
        {
19
            ...
20
}
21
22
void put_PSTR (const char * fmt, ...)
23
{
24
    va_list vlist;
25
    va_start (vlist, fmt);
26
27
    put_va (fmt, vlist);
28
29
    va_end (vlist);
30
}

Die Format-String muss im Flash liegen. Um nicht jedesmal PSTR oder so 
eintippen zu müssen, gibt's ein Makro:
1
#include <avr/pgmspace.h>
2
3
// mind the blank before the colon!
4
#define put_P(y,z...)   put_PSTR (PSTR(y) , ##z)
5
extern void put_PSTR (const char *, ...);

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.