sscanf-Parameter durch Funktion hindurch geben

OP #1947163
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
#1947191
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".
1
extern void error_exit(const char *msg, ...) 
2
  __attribute__ ((format (printf, 1, 2)));
3

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

7
  va_start(va, msg);
8
  vfprintf(stderr, msg, va);
9
  va_end(va);
10
  exit(EXIT_FAILURE);
11
}

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.
#1947217
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.
#1952642
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.
OP #1953026
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
Gast #1953127
Lesenswert?

Ich versuche das gerade um mir für SDL eine TTF-Printf-Ausgabe zu 
basteln, allerdings wills nich so ganz.
1
int ttf_printf(const char *fontfile, int size, int x, int y, const char *format, ...) {
2
    va_list va;
3
    va_start(va, format);
4
    printf("%s %d %d %d: ",fontfile,size,x,y);
5
    printf(format, va);
6
    va_end(va);
7
    return 0;
8
}
Der Aufruf sieht so aus:
1
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?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren