Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
221 views
in Technique[技术] by (71.8m points)

c - sprintf() with automatic memory allocation?

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<
", 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!

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Here is the original answer from Stack Overflow. As others have mentioned, you need snprintf not sprintf. Make sure the second argument to snprintf is zero. That will prevent snprintf from writing to the NULL string that is the first argument.

The second argument is needed because it tells snprintf that enough space is not available to write to the output buffer. When enough space is not available snprintf returns the number of bytes it would have written, had enough space been available.

Reproducing the code from that link here ...

char* get_error_message(char const *msg) {
    size_t needed = snprintf(NULL, 0, "%s: %s (%d)", msg, strerror(errno), errno) + 1;
    char  *buffer = malloc(needed);
    sprintf(buffer, "%s: %s (%d)", msg, strerror(errno), errno);
    return buffer;
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...