Skip to content

Instantly share code, notes, and snippets.

@tamaskenez
Last active October 21, 2015 10:42
Show Gist options
  • Select an option

  • Save tamaskenez/1b736ee1af5e10d6de8c to your computer and use it in GitHub Desktop.

Select an option

Save tamaskenez/1b736ee1af5e10d6de8c to your computer and use it in GitHub Desktop.
stringf - printf to std::string
#ifndef STRING_INCLUDED_24298342934
#define STRING_INCLUDED_24298342934
#include <cstdio>
#include <string>
#include <cerrno>
// This file defines the function
//
// std::string stringf(const char* format_string, args...)
//
// which works just like `printf` or `sprintf` except the result
// is returned in an `std::string`
// It also handles std::string arguments natively:
//
// std::string ss("something");
// stringf("Foo: %s", ss)
//
// Also defined is the macro
//
// CSTRINGF(format_string, args..)
//
// Which is just `stringf().c_str()`
template <typename H, typename... Args>
std::string stringf(const char* s, const H& h, Args... args)
{
#ifndef _MSC_VER
#define SOME_SNPRINTF snprintf
#else
#define SOME_SNPRINTF _snprintf
#endif
const size_t kBufsize = 4096;
char buf[kBufsize];
int r = SOME_SNPRINTF(buf, kBufsize, s, h, args...);
if (0 <= r && r < kBufsize)
return buf;
errno = 0;
#ifdef _MSC_VER
if (r < 0)
r = _snprintf(0, 0, s, h, args...);
#endif
if (r < 0)
return "<SPRINTF ERROR>";
std::vector<char> buf2(r + 1);
buf2[0] = 0;
SOME_SNPRINTF(buf2.data(), r + 1, s, h, args...);
return buf2.data();
#undef SOME_SNPRINTF
}
template <typename... Args>
std::string stringf(const char* s, const std::string& ss, Args... args)
{
return stringf(s, ss.c_str(), args...);
}
#define CSTRINGF(x, ...) (::sx::stringf(x, __VA_ARGS__).c_str())
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment