tags:

views:

149

answers:

3

Hello!

I'm searching for a sprintf()-like implementation of a function that automatically allocates required memory. So I want to say

char* my_str = dynamic_sprintf( "Hello %s, this is a %.*s nice %05d string", a, b, c, d );

and my_str retrieves the adress of an allocated memory that holds the result of this sprintf().

In another forum, I read that this can be solved like this:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main()
{
    char*   ret;
    char*   a = "Hello";
    char*   b = "World";
    int     c = 123;

    int     numbytes;

    numbytes = sprintf( (char*)NULL, "%s %d %s!", a, c, b );
    printf( "numbytes = %d", numbytes );

    ret = (char*)malloc( ( numbytes + 1 ) * sizeof( char ) );
    sprintf( ret, "%s %d %s!", a, c, b );

    printf( "ret = >%s<\n", ret );
    free( ret );

    return 0;
}

But this immediatelly results in a segfault when the sprintf() with the NULL-pointer is invoked.

So any idea, solution or tips? A small implementation of a sprintf()-like parser that is placed in the public domain would already be enought, then I could get it myself done.

Thanks a lot!

+4  A: 
  1. If possible, use snprintf -- it gives an easy way to measure the size of data that would be produced so you can allocate space.
  2. If you really can't do that, another possibility is printing to a temporary file with fprintf to get the size, allocate the memory, and then use sprintf. snprintf is definitely the preferred method though.
Jerry Coffin
+2  A: 

GNU and BSD have asprintf and vasprintf that are designed to do just that for you. It will figure out how to allocate the memory for you and will return null on any memory allocation error.

asprintf does the right thing with respect to allocating strings -- it first measures the size, then it tries to allocate with malloc. Failing that, it returns null. Unless you have your own memory allocation system that precludes the use of malloc, asprintf is the best tool for the job.

The code would look like:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main()
{
    char*   ret;
    char*   a = "Hello";
    char*   b = "World";
    int     c = 123;

    ret = asprintf( "%s %d %s!", a, c, b );
    if (ret == NULL) {
        fprintf(stderr, "Error in asprintf\n");
        return 1;
    }

    printf( "ret = >%s<\n", ret );
    free( ret );

    return 0;
}
Mike Axiak
asprintf() would be the function of my choice - but unfortunatelly, its non standard and not portable - bad!
the-shamen
@the-shamen - what you are asking for is by definition non standard and not portable. Get the source for `asprintf` and pull it into your project if you need to, or reimplement it independently.
bstpierre
+1  A: 

The GLib library provides a g_strdup_printf function that does exactly what you want, if linking against GLib is an option. From the documentation:

Similar to the standard C sprintf() function but safer, since it calculates the maximum space required and allocates memory to hold the result. The returned string should be freed with g_free() when no longer needed.

Paul Kuliniewicz
Hello, thanks! But this is only glibc, I need a platform-independent solution. So maybe its better to do this by myself?
the-shamen