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
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.
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
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.
Also wenn dann dein Fall auftreten würde, käme dann eine Fehler oder Warnmeldung beim kompilieren?
Ja. Das hätte man übrigens auch im Handbuch von gcc nachlesen könne.
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
geht nicht. Zumindest nicht ohne unportable Schweinereien.
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.
Wo soll es denn stehen? Ich finde es jedenfalls nicht. Wenn mir jemand ein passendes Stichwort sagt, finde ich es ja vielleicht.
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.
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.
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
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.
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?
Du kannst nicht einfach eine va_list als Argument an printf übergeben. Du mußt stattdessen vprintf benutzen.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.