有没有办法确定sprintf将写入多少个字符?

Scr*_*dib 12 c++ string printf

我在C++工作.

我想用sprintf编写一个可能很长的格式化字符串(特别是像_snprintf_s这样的安全计数版本,但想法是一样的).在编译时大致的长度是未知的,所以我将不得不使用一些动态分配的内存而不是依赖一个大的静态缓冲区.有没有办法确定特定sprintf调用需要多少个字符,所以我总能确定我有足够大的缓冲区?

我的后备是我只需要格式字符串的长度,加倍它,并尝试.如果它工作,很好,如果不是,我只会加倍缓冲区的大小,然后再试一次.重复直到它适合.不完全是最聪明的解决方案.

看起来C99支持将NULL传递给snprintf来获取长度.我想我可以创建一个模块来包装该功能,如果没有别的,但我对这个想法不是很疯狂.

也许对"/ dev/null"/"nul"的fprintf可能会起作用吗?还有其他想法吗?

编辑:或者,是否有任何方法可以"spunk"sprintf所以它在中间写入?如果可能的话,它可以填充缓冲区,处理它,然后从它停止的地方开始重新填充.

Nat*_*man 22

手册页snprintf说:

   Return value
       Upon  successful  return,  these  functions return the number of
       characters printed (not including the trailing '\0' used to  end
       output to strings).  The functions snprintf and vsnprintf do not
       write more than size bytes (including the  trailing  '\0').   If
       the output was truncated due to this limit then the return value
       is the number of characters (not including  the  trailing  '\0')
       which  would  have  been  written  to the final string if enough
       space had been available. Thus, a return value of size  or  more
       means  that  the  output  was  truncated.  (See also below under
       NOTES.)  If an output error is encountered, a negative value  is
       returned.

这意味着您可以调用snprintf大小为0.什么都不会被写入,返回值将告诉您需要为字符串分配多少空间:

int how_much_space = snprintf(NULL, 0, fmt_string, param0, param1, ...);
Run Code Online (Sandbox Code Playgroud)


Mic*_*urr 5

正如其他人所提到的,snprintf()将返回缓冲区中所需的字符数,以防止输出被截断.您可以使用0缓冲区长度参数调用它来获取所需的大小,然后使用适当大小的缓冲区.

为了略微提高效率,可以使用一个足够大的缓冲区来调用它,snprintf()如果输出被截断的话,只需要进行第二次调用.为了确保缓冲区在这种情况下正确释放,我经常会使用一个auto_buffer<>为我处理动态内存的对象(并且在堆栈上有默认缓冲区以避免在正常情况下分配堆) .

如果您正在使用Microsoft编译器,则MS具有非标准_snprintf(),其具有严重限制,即不总是空终止缓冲区并且不指示缓冲区应该有多大.

为了解决微软的不支持问题,我使用snprintf()Holger Weiss 的近公共域名.

当然,如果缺少非MS C或C++编译器snprintf(),上述链接中的代码也应该可以正常工作.


jas*_*ray 0

我已经寻找过你所说的相同功能,但据我所知,像C99方法这样简单的东西在C++中是不可用的,因为C++目前没有合并C99中添加的功能(例如snprintf) 。

您最好的选择可能是使用 stringstream 对象。它比明确编写的 sprintf 调用要麻烦一点,但它会起作用。