Goal: serialize data to JSON.
Issue: i cant know beforehand how many chars long the integer is.
i thought a good way to do this is by using sprintf()
size_t length = sprintf(no_buff, "{data:%d}",12312);
char *buff = malloc(length);
snprintf(buff, length, "{data:%d}",12312);
//buff is passed on ...
Of course i can use a stack variable like char a[256]
instead of no_buff
.
Question: But is there in C a utility for disposable writes like the unix /dev/null
?
Smth like this:
#define FORGET_ABOUT_THIS ...
size_t length = sprintf(FORGET_ABOUT_THIS, "{data:%d}",12312);
p.s. i know that i can also get the length of the integer through log but this ways seems nicer.
To just obtain the length you can write:
Note that the return type is
int
. It may return-1
in case of some sort of error. Make sure your input data doesn't include long strings that might cause the total length to exceedINT_MAX
!This isn't strictly an answer to your question, but you may find it helpful nonetheless. It is not portable, but if you're running this on glibc, you can simply use
asprintf()
instead, which will do the memory allocation for you.You can call
int len = snprintf(NULL, 0, "{data:%d}", 12312)
to test how much space you need.snprintf
will print at mostsize
characters, wheresize
is the second argument, and return how many characters would have been necessary to print the whole thing, not counting the terminating'\0'
. Because you pass in 0, it won't actually write anything out (and thus will avoid any null pointer exception that would happen by trying to dereferenceNULL
), but it will still return the length that is needed to fit the whole output, which you can use to allocate your buffer.At that point you can allocate and print to your buffer, remembering to include one more for the trailing
'\0'
:Printf supports %n format parameter, which means "write position of %n in output string to int value pointed by x-parameter), so:
Should works!
If you check the performance, you will running snprintf without an output buffer will take roughly the same time as a full invocation.
So I recommend you to use a smaller buffer just in case, and only call it a second time if the returned size exceeded the buffer size.
This uses C++'s
std::string
but I guess you can adapt it for your needs.This code will run 2x faster for strings under 1k compared to the longer ones.
Since C is where simple language, there is no such thing as "disposable buffers" -- all memory management are on programmers shoulders (there is GNU C compiler extensions for these but they are not standard).
There is much easier solution for your problem.
snprintf
knows!On C99-compatible platforms call snprintf with NULL as first argument:
In older Visual Studio versions (which have non-C99 compatible CRT), use
_scprintf
instead ofsnprintf(NULL, ...)
call.