2013-02-24 9 views
5

Ich habe die folgende C-Funktion mit einer variablen Anzahl von Argumenten, die die char* word durch eine Hash-Tabelle suchen sollten, und schreiben true oder false in einer Datei, die, falls angegeben, ist der zweite Parameter; ansonsten ist es stdout.Odd Verhalten der Funktion mit variabler Anzahl von Parametern in C

Es funktioniert gut, wenn ich den Namen der Datei angeben, ist das Problem, wenn ich nicht (z. B.). In diesem Fall schreibt es das Ergebnis in eine Datei mit dem Namen foo anstelle von stdout.

Was ist die Ursache?

void find(char* word, ...) 
{ 
va_list list; 
char *fname = NULL; 
va_start(list, word); 
FILE* f; 
fname = strdup(va_arg(list, char*)); 
va_end(list); 
if (<condition>) // condition suited for the case in which the file name is received 
    f = fopen(fname, "a"); 
else 
    f = stdout; 
if (member(word)) 
    fprintf(f, "True\n"); 
else 
    fprintf(f, "False\n"); 
} 

Anstelle von <condition> Ich habe fname != NULL versucht und strlen(fname) > 0 aber diejenigen nicht gelten und es hält fname als word sehen, wenn fname nicht angegeben ist.

Vielen Dank für Ihre Hilfe.

+1

varargs sollen nicht auf diese Weise verwendet werden. Sie verwenden besser 'void find (char * word, char * dateiname)' und überprüfen, ob 'filename'' NULL' ist und wenn ja, schreiben Sie in stdout. Vergessen Sie auch nicht, die geöffnete Datei zu schließen, wenn Sie eine Datei geöffnet haben. –

Antwort

6

Von va_* ‚s Manpage:

Wenn es kein nächstes Argument ist, oder wenn der Typ mit der Art des tatsächlichen nächsten Arguments nicht kompatibel (wie nach dem Argumente Standard gefördert Werbeaktionen), zufällige Fehler auftreten.

Wenn Sie eine Variable Parameterliste verwenden möchten, müssen Sie irgendeine Art von Terminator für die Liste entwickeln (zB fügen immer ein Dummy NULL Argument):

find (word, NULL); 
find (word, filename, NULL); 

oder liefern die Anzahl der Parameter als Parameter:

find (1, word); 
find (2, word, filename); 
+0

OK, danke für die Erinnerung an mich. Es arbeitet mit NULL am Ende der Liste. Anfangs dachte ich, dass NULL (oder ein anderes Verhalten) für Argumente, die nicht empfangen wurden, irgendwie impliziert wurde, aber es weiß selbst nicht, wann die Liste endet. – thehousedude

Verwandte Themen