[SOLVED] C equivalent of Python format method

Issue

let me say at first I’m completely aware of sprintf and printf in C, But they don’t meet what I need.

What I want is something like a function which does return formatted string and its parameters are just like printf. e.g.:
char *formatted = format("%c%s Mund%c!", '¡', "Hola", 'o');

Has C a built-in function like that? or it should be implemented by hand?
If the latter, How to implement such function?

It is worth noting that:

  1. string length is unknown
  2. I don’t want to print the string

As a side note: I’ll not use c++, and I use mingw-64 gcc

Solution

There isn’t an equivalent function unless you make one yourself because, unlike python, strings in C are simple arrays and it’s you who is responsible for allocating as much memory as you need, passing a pointer to a function, and freeing it later. That’s why in functions like sprintf you need to specify an output array (and optionally a size value in variants like snprintf).

A custom implementation would be something like this (not including error checks to keep things simple):

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

#define STRSIZE 256

char* my_sprintf(const char* fmt, ...) {
    /* Create a temporary buffer */
    char temp[STRSIZE];
    /* Get variadic arguments */
    va_list args;
    va_start(args, fmt);
    /* Use the variadic argument variant of snprintf
     * The return value is the number of characters that would have been written,
     * if the buffer was sufficiently large. We use this to determine if we
     * need to repeat on a larger buffer to account for strings of any length */
    int len = vsnprintf(result, STRSIZE, fmt, args);
    /* Cleanup */
    va_end(args);
    /* If the entire string fits in the temp buffer, return a copy */
    if (len < STRSIZE)
        return strdup(temp);
    /* Otherwise, allocate enough memory and repeat */
    char* result = (char*)malloc(len + 1); // +1 for the null terminator
    /* The variadic argument pack is consumed already, so recreate it */
    va_start(args, fmt);
    /* Use the variadic argument variant of sprintf
     * (we already have enough allocated memory now, so no need for snprintf) */
    vsprintf(result, fmt, args);
    /* Cleanup */
    va_end(args);
    return result;
}

When you’re done, don’t forget to free the returned pointer!

char* my_string = my_sprintf("My %s", "format");
...
free(my_string);

Answered By – guard3

Answer Checked By – Willingham (BugsFixing Volunteer)

Leave a Reply

Your email address will not be published.