Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

building a string out of a variable amount of arguments

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


int main(int argc, char * argv[])
{
    char *arr[] = { "ab", "cd", "ef" };
    char **ptr, **p, *str;
    int num = 3;
    int size = 0;

    ptr = calloc(num, 4);
    p = ptr;

    for (; num > 0; num--)
            size += strlen(*(p++) = arr[num - 1]);

    str = calloc(1, ++size);
    sprintf(str, "%s%s%s", ptr[0], ptr[1], ptr[2]);

    printf("%s\n", str);

    return 0;
}

output: "efcdab" as expected.

now, this is all fine and suitable if the argument count to sprintf is predetermined and known. what i'm trying to achieve, however, is an elegant way of building a string if the argument count is variable (ptr[any]).

first problem: 2nd argument that is required to be passed to sprintf is const char *format.
second: the 3rd argument is the actual amount of passed on arguments in order to build the string based on the provided format.

how can i achieve something of the following:

sprintf(str, "...", ...)

basically, what if the function receives 4 (or more) char pointers out of which i want to build a whole string (currently, within the code provided above, there's only 3). that would mean, that the 2nd argument must be (at least) in the form of "%s%s%s%s", followed by an argument list of ptr[0], ptr[1], ptr[2], ptr[3].

how can make such a 'combined' call, to sprintf (or vsprintf), in the first place? things would be easier, if i could just provide a whole pointer array (**ptr) as the 3rd argument, instead.. but that does not seem to be feasible? at least, not in a way that sprintf would understand it, so it seems.. as it would need some special form of format.

ideas / suggestions?

like image 991
XXL Avatar asked Nov 13 '22 21:11

XXL


1 Answers

karlphillip's suggestion of strcat does seem to be the solution here. Or rather, you'd more likely want to use something like strncat (though if you're working with a C library that supports it, I'd recommend strlcat, which, in my opinion, is much better than strncat).

So, rather than sprintf(str, "%s%s%s", ptr[0], ptr[1], ptr[2]);, you could do something like this:

int i;

for (i = 0; i < any; i++)
    strncat(str, arr[i], size - strlen(str) - 1);

(Or strlcat(str, arr[i], size);; the nice thing about strlcat is that its return value will indicate how many bytes are needed for reallocation if the destination buffer is too small, but it's not a standard C function and a lot of systems don't support it.)

like image 127
JAB Avatar answered Jan 06 '23 22:01

JAB