www.mikrocontroller.net

Forum: Compiler & IDEs va_list an vsprintf() weiterreichen


Autor: Oleg R. (m_bedded)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

folgende Herausforderung. Man möchte eine va_list-Konstante festlegen 
und an vsprintf() weitergeben.
int8u_t X = 222;
int16u_t Y = 333;

va_list myarglist[] = {&X, &Y};

char mystring[10];

void myprint (char *s, va_list l)
{
  vsprintf(s, "%d %d", l);
}

void main (void)
{
  myprint(mystring, myarglist);
}

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).

Autor: Hannes Jaeger (pnuebergang)
Datum:

Bewertung
0 lesenswert
nicht 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.
#include <inttypes.h> 

typdefe struct {
   uint8_t x;
   uint16_t y;
} Data;

Data data = { 222, 333 };

void myprint (char *s, Data *l)
{
   sprintf(s, "%"PRIu8 " %"PRIu16, l->x, l->y);
}

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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:
#include <stdarg.h>

// Decode format string <fmt> and dispatch to respective putter

static void
put_va (const char * fmt, va_list args)
{
    put_local = put_char;

    while (1)
    {
        char c = pgm_read_byte (fmt++);

        if ('\0' == c)
            return;

        if ('%' == c)
        {
            ...
}

void put_PSTR (const char * fmt, ...)
{
    va_list vlist;
    va_start (vlist, fmt);

    put_va (fmt, vlist);

    va_end (vlist);
}

Die Format-String muss im Flash liegen. Um nicht jedesmal PSTR oder so 
eintippen zu müssen, gibt's ein Makro:
#include <avr/pgmspace.h>

// mind the blank before the colon!
#define put_P(y,z...)   put_PSTR (PSTR(y) , ##z)
extern void put_PSTR (const char *, ...);

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.