A previous question顯示了一個打印到字符串的好方法。答案涉及va_copy:va_copy - 移植到Visual C++?
std::string format (const char *fmt, ...);
{
va_list ap;
va_start (ap, fmt);
std::string buf = vformat (fmt, ap);
va_end (ap);
return buf;
}
std::string vformat (const char *fmt, va_list ap)
{
// Allocate a buffer on the stack that's big enough for us almost
// all the time.
s ize_t size = 1024;
char buf[size];
// Try to vsnprintf into our buffer.
va_list apcopy;
va_copy (apcopy, ap);
int needed = vsnprintf (&buf[0], size, fmt, ap);
if (needed <= size) {
// It fit fine the first time, we're done.
return std::string (&buf[0]);
} else {
// vsnprintf reported that it wanted to write more characters
// than we allotted. So do a malloc of the right size and try again.
// This doesn't happen very often if we chose our initial size
// well.
std::vector <char> buf;
size = needed;
buf.resize (size);
needed = vsnprintf (&buf[0], size, fmt, apcopy);
return std::string (&buf[0]);
}
}
我遇到的問題是,上面的代碼沒有端口到Visual C++,因爲它不提供va_copy(甚至__va_copy)。那麼,有沒有人知道如何安全地移植上述代碼?據推測,我需要做一個va_copy副本,因爲vsnprintf破壞性地修改了傳遞的va_list。
我在VC++中實現了類似的東西,並且從來不需要使用`va_copy()`。當您嘗試使用而不使用副本時會發生什麼? – 2009-02-17 18:57:05
誰知道... 它似乎工作。即使這樣做,但並不意味着它是安全的。 – user48956 2009-02-17 19:07:32
顯然va_copy()是一個C99的東西。對於VC++來說,你可以多次使用原始的va_list,而不必擔心副本。 vsnprintf不會嘗試修改傳遞的列表。 – 2009-02-17 19:50:16