Skip to content

Instantly share code, notes, and snippets.

@svenk
Created July 3, 2019 08:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save svenk/6cb0e979e4c54901f1844c375d952ffc to your computer and use it in GitHub Desktop.
Save svenk/6cb0e979e4c54901f1844c375d952ffc to your computer and use it in GitHub Desktop.
Convenient C's printf in C++
// this is a buffer-overflow-safe version of sprintf
// source: http://stackoverflow.com/a/69911
// if you need something more mature, consider https://github.com/fmtlib/fmt
// the advantage of this snippet is that it can be really easily added to smallish
// codes/libraries. Usage is like C's vprintf et al. but with a C++ std::string as a result.
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. Be prepared to allocate dynamically if it doesn't fit.
size_t size = 1024;
char stackbuf[1024];
std::vector<char> dynamicbuf;
char *buf = &stackbuf[0];
va_list ap_copy;
while (1) {
// Try to vsnprintf into our buffer.
va_copy(ap_copy, ap);
int needed = vsnprintf (buf, size, fmt, ap);
va_end(ap_copy);
// NB. C99 (which modern Linux and OS X follow) says vsnprintf
// failure returns the length it would have needed. But older
// glibc and current Windows return -1 for failure, i.e., not
// telling us how much was needed.
if (needed <= (int)size && needed >= 0) {
// It fit fine so we're done.
return std::string (buf, (size_t) needed);
}
// vsnprintf reported that it wanted to write more characters
// than we allotted. So try again using a dynamic buffer. This
// doesn't happen very often if we chose our initial size well.
size = (needed > 0) ? (needed+1) : (size*2);
dynamicbuf.resize (size);
buf = &dynamicbuf[0];
}
}
std::string sformat(const char *fmt, ...) {
va_list ap;
va_start (ap, fmt);
std::string buf = vformat (fmt, ap);
va_end (ap);
return buf;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment