In C there's more than one way to do it, depending how you would like to allocate the memory[*]. For the straightforward option of allocating it from the heap:
len = snprintf(0, 0, "%d bottles, %d shelves, room %d\n", one, two, three);
char *result = malloc(len+1);
if (result == 0) { /* handle error */ }
snprintf(result, len+1, "%d bottles, %d shelves, room %d\n", one, two, three);
/* some time later */
free(result);
Beware non-standard implementations of snprintf
, that don't return the length when the buffer is exceeded. Check your documentation.
In C++, snprintf
is not in the standard, and even where it is available, the above code would need to cast the result of malloc[**]. C++ adds the option of using stringstreams:
std::stringsteam r;
r << one << " bottles, " << two << " shelves, room " << three << "\n";
std::string result = r.str();
// if you absolutely need a char*, use result.c_str(), but don't forget that
// the pointer becomes invalid when the string, "result" ceases to exist.
This saves messing with buffer lengths, makes resource management easier, and avoids the risk with printf
and friends that you could pass an argument of the wrong type for the format specifier. It's usually the preferred option.
It is however less flexible in some circumstances: the format is hard-wired into the code rather than contained in a format string, so it's harder to make the text configurable. It can also be a bit harder to read, for instance it's not at all uncommon to leave out a space character on the first version of any such line of code. But if you want to use the snprintf
approach in C++, and snprintf
is available in your implementation, then you can take advantage of C++'s easier memory management as follows:
len = std::snprintf(0, 0, "%d bottles, %d shelves, room %d\n", one, two, three);
std::vector<char> r(len+1);
std::snprintf(&r[0], r.size(), "%d bottles, %d shelves, room %d\n", one, two, three);
char *result = &r[0];
// again, "result" is only valid as long as "r" is in scope
[*] Note that you cannot "store" a string in a char*
, because a char*
is just a pointer. You can store a pointer to a string in a char*
, but the string itself is a completely separate thing.
[**] because C and C++ ARE DIFFERENT LANGUAGES!