How to printf a length-delimited string

Thursday, November 15, 2012.

Sometimes you're dealing with a string that isn't null-delimited but rather length-delimited, and you wind up doing somersaults just to print it out:

void logit(const char *string, size_t length) {
  char buf[255];
  strncpy(buf, string, sizeof(buf));
  buf[sizeof(buf) - 1] = '\0';
  fprintf(stderr, "debug: %s\n", buf);
}

The extra copying isn't necessary, and you don't have to live with the potential length-truncation either. Did you know printf(3) can format length-delimited strings directly? Buried in the man page is this little gem:

The precision

An optional precision, in the form of a period ('.') followed by an optional decimal digit string. Instead of a decimal digit string one may write "*" or "*m$" (for some decimal integer m) to specify that the precision is given in the next argument, or in the m-th argument, respectively, which must be of type int. This gives ... the maximum number of characters to be printed from a string for s and S conversions.

With that in mind, we can just write:

void logit(const char *string, size_t length) {
  fprintf(stderr, "debug: %.*s\n", (int)length, string);
}
Posted by Alan on Thursday, November 15, 2012.