Friday, December 19, 2008

Nice feature of snprintf()

Hi all,

Yesterday I learned a feature which I'm sure should be described in every C book. To be honest, 'man snprintf' describes it as a part of C99, but I've never read the article completely.

Often when you construct a string using 'snprintf()' you need to allocate enough space for the buffer. But it's not possible to know how much you may need, so usually we just do something like this:


char buf1[1024];
/* or */
char *buf2 = malloc(1024);

which is not correct even if you are 100% sure that you string is just a "Hello world". Btw, you are wasting your stack space in first example.

So the trick here is to call 'snprintf()' twice:

int len = 1 + snprintf(NULL, 0, "%s, %s\n", "Hello", "world") ;
char *buf = malloc(len);
snprintf(buf, len, "%s, %s\n", "Hello", "world");

snprintf's behavior in C99 is to allow buffer to be NULL, but return number of bytes that would have been written to buffer. Note, second parameter should be zero too :)

5 comments:

  1. hm. I don`t know C well, but maybe

    char *buf = malloc(len);

    ?

    ReplyDelete
  2. Oops, of course! Renamed `num` to `len` to have self-explanatory name. But as it always happens...

    ReplyDelete
  3. snprintf() returns -1 if you have an encoding error, so you need to make sure len > 0 before calling malloc()

    ReplyDelete
  4. There is also asprintf(). asprintf is identical to the simpler sprintf, but is much easier to use, because it dynamically allocates the string used to hold the output.

    ReplyDelete