2010-03-10 35 views
6

Hãy nói rằng tôi muốn làm một cái gì đó như thế nàyC, Đối phó với chức năng lập luận biến

void my_printf(char *fmt,...) { 
char buf[big enough]; 
sprintf(buf,fmt,...); 
} 

cách đúng đắn qua số biến của các đối trực tiếp đến một chức năng với chấp nhận lập luận biến là gì?

+0

Làm cách nào để biết bộ đệm đủ lớn? Và bạn thực sự nên trả về số lượng chuyển đổi được thực hiện bởi sprintf(), người dùng khác không có cách nào để biết chức năng này hoạt động. –

+0

Tôi vạch ra mọi thứ không cần thiết để minh họa quan điểm của tôi. Rõ ràng trong mã phát hành của tôi, tôi hoàn toàn kỹ lưỡng hơn :) – Mike

Trả lời

9

sprintf có dạng va_list được gọi là vsprintf. Vượt qua va_list bạn xây dựng cục bộ cho nó làm đối số cuối cùng.

void my_printf(char *fmt,...) { 
va_list ap; 
va_start(ap, fmt); 

char buf[big enough]; 
vsprintf(buf,fmt,ap); 

va_end(ap); 
} 
+3

Tiêu đề tác vụ là ''. –

+0

Nếu có, bạn nên sử dụng 'vsnprintf'. –

1

Tôi không chắc chắn như thế nào hữu ích mã này sẽ được, vì nó là C++, nhưng nó cho thấy làm thế nào để kiểm tra, sử dụng Win32 cụ thể chức năng vsnprintf(), mà bộ đệm được phân bổ là đủ lớn và nếu không muốn nói phân bổ một cái lớn hơn. Và nó trả về một chuỗi :: std, vì vậy bạn sẽ phải sử dụng malloc/realloc để xử lý điều đó. Nhưng địa ngục là gì:

string Format(const char * fmt, ...) { 
    const int BUFSIZE = 1024; 
    int size = BUFSIZE, rv = -1; 
    vector <char> buf(size); 
    do { 
     va_list valist; 
     va_start(valist, fmt); 
     // if vsnprintf() returns < 0, the buffer wasn't big enough 
     // so increase buffer size and try again 
     rv = _vsnprintf(&buf[0], size, fmt, valist); 
     va_end(valist); 
     size *= 2; 
     buf.resize(size); 
    } 
    while(rv < 0); 
    return string(&buf[0]); 
} 
-1

Bạn có thể cho chúng tôi các chức năng kiểu vsprintf để in kiểu in cho thông số độ dài biến của bạn. Tuy nhiên, không có việc tái đấu thầu để làm như vậy. Bạn có thể nếu bạn chọn viết hàm của bạn để tiếp tục chấp nhận tham số cho đến khi nó gặp một con trỏ null.

va_list ap; 
char *param; 
va_start(ap,fmt); 
param = va_arg(ap,char*); 
while(param) 
{ 
do something... 
param = va_arg(ap,char*); 
} 

hoặc bạn có thể có số lượng các thông số như param đầu tiên chức năng của bạn

void my_printf(int param_num,...) 
{ 
va_list ap; 
char *param; 
va_start(ap,fmt); 
while(param_num) 
{ 
do something... 
param = va_arg(ap,char*); 
param_num--; 
} 

} 

của nó thực sự tùy thuộc vào bạn, khả năng là vô hạn. Tôi nghĩ rằng yêu cầu thực sự duy nhất cho hình elip là nó có ít nhất một tham số trước dấu ba chấm.

+0

yêu cầu người dùng chỉ định số tham số sẽ là một thảm họa thiết kế – Mike

+1

điểm của tôi là ... không phải là chim bồ câu được đục lỗ thành một cách sử dụng nhất định. Người dùng của hàm có thể quyết định điều gì là tốt nhất cho tình huống của họ. Việc chuyển số tham số không khác với số được nhúng trong một chuỗi ... tức là sprintf ("% d% d", a, b) chỉ giống như yourprintf (2, a, b), sprintf là dễ bị lỗi người dùng. – Medran

Các vấn đề liên quan