www.mikrocontroller.net

Forum: Compiler & IDEs sscanf-Parameter durch Funktion hindurch geben


Autor: Richard W. (richi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

ich möchte mir eine Funktion machen, in der u.a sscanf vorkommt. Die 
Zeigerliste, die man normalerweise in sscanf einfügt,
z.B. sscanf(text,"%d%d%d...",&a,&b,&c)  => &a,&b,&c
soll genauso an meine Funktion übergeben werden, wobei diese Funktion 
dann genau diese Variablen an die sich der Funktion befindenden 
sscanf-Funktion übergibt.

Ich hoffe es ist euch klar geworden.

Wie baut man sowas auf?


Viele Grüße
Richi

Autor: Sebastian C. (basti79)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin,

ich hab sowas mal für printf gemacht, eigentlich das gleiche und das 
solltest du dann dementsprechend anpassen können. Die magischen Worte 
zum Googlen sind hier "variable argument list".
extern void error_exit(const char *msg, ...) 
  __attribute__ ((format (printf, 1, 2)));

void error_exit(const char *msg, ...) {
  va_list va;

  va_start(va, msg);
  vfprintf(stderr, msg, va);
  va_end(va);
  exit(EXIT_FAILURE);
}

Das _attribute_ beim Prototyp brauchst du nicht unbedingt, aber 
dadurch kann der Compiler den Syntax der variablen Argumente prüfen; ist 
glaube ich auch gcc spezifisch.

Greets
  Basti.

Autor: Richard W. (richi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank.

Was genau bewirkt das mit dem _atributte_?
Das habe ich noch nicht so ganz begriffen.

Der Rest ist mir jetzt klar.

Viele Grüße
Richi

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Richard W. schrieb:
> Vielen Dank.
>
> Was genau bewirkt das mit dem _atributte_?


Das teilt dem gcc mit, wie das bei dieser Funktion mit den variadischen 
Argumenten (so heißt eine variable Argumentliste im Jargon) gedacht ist: 
Deine Funktion verhält sich so wie printf, d.h. ein String steuert die 
Auswertung der restlichen Argumente.

Das ermöglicht dem gcc etwas, was normalerweise nicht möglich ist:
Er prüft, ob deine %-Kürzel zur tatsächlichen restlichen Argumentliste 
passen. Dies deshalb, weil es ja für printf keinen herkömmlichen 
Protoypen der Funktion geben kann. Denn da steht ja nur:

void printf( const char*, ... )

das also beliebige andere Argumente kommen können. Und wenn du zb

  double j = 5.0;
  print( "%d", j );

machst, dann gibt das die tollsten Effekte. %d ist nun mal für int und 
nicht für double, d.h. das passt nicht zusammen. Nur mit Prüfung des 
Prototypen ist das nicht detektierbar. Also hat man dem gcc eine 
Erweiterung eingebaut, die den Compiler in die Lage versetzt, hier mal 
sein Prototypen-Prüfschema über Bord zu werfen und stattdessen mit dem 
String die restlichen Argumente auf Plausibilität abzuklopfen.

Autor: Richard W. (richi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also wenn dann dein Fall auftreten würde, käme dann eine Fehler oder 
Warnmeldung beim kompilieren?

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja. Das hätte man übrigens auch im Handbuch von gcc nachlesen könne.

Autor: Richard W. (richi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK, alles klar.

Vielen Dank!!!

Richi

Autor: Richard W. (richi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo nochmal.

Wie kann ich denn noch Argumente von der Funktion her an sscanf anreihen 
lassen?


va_list  => &a,&b,&c  (übergebene Paramter variabler Anzahl)

Funktion fügt &d hinzu =>  &a,&b,&c,&d

==> sscanf(text,format,&a,&b,&c,&d)


Viele Grüße
Richi

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
geht nicht.

Zumindest nicht ohne unportable Schweinereien.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Richard W. schrieb:
> Wie kann ich denn noch Argumente von der Funktion her an sscanf anreihen
> lassen?

Auch das kann man im gcc-Handbuch nachlesen.

Autor: Richard W. (richi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wo soll es denn stehen?
Ich finde es jedenfalls nicht.

Wenn mir jemand ein passendes Stichwort sagt, finde ich es ja 
vielleicht.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
variadic ist sicher kein schlechtes Stichwort (wobei ich nicht weiß,
ob die glibc für so einen Fall etwas Sinnvolles kennt).

Ich kann mir auch nicht recht vorstellen, daß es irgendwie
sinnvoll ist. Ohne den Formatstring zu verlängern, ist es doch
ziemlich witzlos, irgendwelche Argumente anzuhängen?

Wenn schon, dann auch vielleicht in der glibc zu suchen, statt
beim gcc.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich würds auch lassen.
Solche variadischen Dinge arten ganz schnell in ein Nightmare aus, wenn 
man nicht aufpasst und sind fehleranfällig bis zum geht nicht mehr.

Autor: Richard W. (richi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Den Formatstring ändert meine Funktion schon, nur das hinten anhängen 
der Parameter für die Funktion funktioniert noch nicht.

Mit dem Stichwort variadic habe ich auch nur Lösungen gefunden, die 
Argumenteliste an die Letzte Stelle zu positionieren, nicht aber die 
Lösung, danach noch Parameter anzuhängen.

Mitlerweile glaube ich aber auch, dass es wirklich zu einem "Nightmare" 
kommt, ich hätte nicht gedacht, dass es so kompliziert ist.

Viele Grüße
Richi

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Richard W. schrieb:
> Wo soll es denn stehen?

Oh, sorry. Ich hatte dein Posting mißverstanden, muß also alles 
zurücknehmen und mich den anderen anschließen. Es gibt meines Wissens 
keinen sinnvollen Weg, die Argumentliste nachträglich zu verändern.

Autor: ichbins (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich versuche das gerade um mir für SDL eine TTF-Printf-Ausgabe zu 
basteln, allerdings wills nich so ganz.
int ttf_printf(const char *fontfile, int size, int x, int y, const char *format, ...) {
    va_list va;
    va_start(va, format);
    printf("%s %d %d %d: ",fontfile,size,x,y);
    printf(format, va);
    va_end(va);
    return 0;
}
Der Aufruf sieht so aus:
ttf_printf("fontbig.ttf", 12, 200, 400, "hello world %d\n", 40);

und das kommt dabei raus:
> fontbig.ttf 12 200 400: hello world -1075731612
Irgendwie kommt das "40" nicht durch und was angezeigt wird, scheint 
irgendwie ins leere zu greifen, kann mir dabei jemand helfen?

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du kannst nicht einfach eine va_list als Argument an printf übergeben. 
Du mußt stattdessen vprintf benutzen.

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.