2013-02-24 23 views
5

Tôi có hàm C sau đây với số lượng đối số thay đổi, được cho là tìm kiếm char* word thông qua một hashtable và viết true hoặc false trong một tệp, nếu được chỉ định, là tham số thứ hai; nếu không, nó là stdout.Hành vi lẻ của hàm có số biến số tham số trong C

Nó hoạt động tốt nếu tôi chỉ định tên của tệp, vấn đề là khi tôi không (ví dụ: find("foo")). Trong trường hợp này, nó ghi kết quả trong một tệp có tên foo thay vì stdout.

Nguyên nhân là gì?

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"); 
} 

Thay <condition> Tôi đã thử fname != NULLstrlen(fname) > 0 nhưng những người không áp dụng và nó vẫn không ngừng nhìn thấy fname như word khi fname không được xác định.

Cảm ơn bạn rất nhiều vì bất kỳ trợ giúp nào bạn có thể cung cấp.

+1

varargs không được cho là được sử dụng theo cách này. Bạn nên sử dụng 'void find (char * word, char * filename)' và kiểm tra nếu 'filename' là' NULL' và nếu như vậy hãy ghi vào stdout. Cũng đừng quên đóng tệp, bạn đã mở, nếu bạn đã mở một tệp. –

Trả lời

6

Từ trang người đàn ông va_* 's:

Nếu không có tranh luận tiếp theo, hoặc nếu loại không tương thích với các loại của đối số tiếp theo thực tế (như đề bạt theo đối số mặc định chương trình khuyến mãi), lỗi ngẫu nhiên sẽ xảy ra.

Nếu bạn muốn sử dụng một danh sách tham số biến, bạn cần phải đưa ra một số loại terminator cho danh sách (ví dụ, luôn luôn thêm một đối số NULL dummy):

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

hoặc cung cấp số lượng tham số làm thông số:

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

OK, cảm ơn vì đã nhớ tôi. Nó hoạt động với NULL ở cuối danh sách. Ban đầu tôi nghĩ rằng NULL (hoặc hành vi khác) đã được ngụ ý bằng cách nào đó cho các đối số mà không nhận được, nhưng nó không biết một mình khi danh sách kết thúc. – thehousedude