Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Given a printf statement in C, how do I construct a char * buffer, and know its length?

I have an MPI process that I need to print to a file. The MPI system uses functional commands like MPI_File_iwrite, which accept a buffer (a char pointer, for instance) and an integer length. Then, the buffer is printed to the file.

So, in order to print what I need to print to the file, I need to somehow replace the printf function with a function that maps the formatting conversion to a char * buffer. This is problematic, since the strings can vary in length...for instance:

printf("something %d, %d, %d, %f, etc.",x,y,z,p,d,...);

How do I recover the string that printf formatting produces, figure out what the length is, and pass it as a char * to the mpi function?

like image 552
Chris Avatar asked Dec 06 '22 16:12

Chris


2 Answers

It looks like you want to use snprintf to a sufficiently-large buffer.

If the buffer was sufficiently large, the return value of snprintf is equal to the number of characters printed. You can compute the length of the output string as the minimum of the size of the buffer and the return value of snprintf.

like image 135
merlin2011 Avatar answered Dec 08 '22 05:12

merlin2011


You can "print" 0 bytes to a NULL pointer with snprintf(). In that case, no string will be written, but snprintf() will still behave normally with respect to its return value. Then you can allocate a large enough buffer.

For instance:

size_t len;
len = snprintf(NULL, 0, "something %d, %d, %d, %f, etc.",x,y,z,p,d,...);
if (len > 0) {
    char *buf = malloc(len + 1);
    snprintf(buf, len + 1, "something %d, %d, %d, %f, etc.",x,y,z,p,d,...);
}

This is only valid in C99 and further.

Notice that snprintf() can return a negative value if there is a conversion error. The are only a few instances where this could happen, but they exist nonetheless. Depending on the specifier, its output could also be zero.

like image 25
giusti Avatar answered Dec 08 '22 04:12

giusti