Domanda

I've been using C# for the last few years, and right now I'm trying to write some C. I'm trying to format a string from an array of values. The "format string" and the array aren't known until runtime.

In C# I can invoke a variadic function with an array, like this:

using System;

namespace ConsoleApplication7
{
    class Program
    {
        static void Main(string[] args)
        {
            string formatString = "{0}.{1}.{2}.{3}";
            string[] formatValues = new[] { "a", "b", "c", "d" };

            string formatted = String.Format(formatString, formatValues);

            //Do something with formatted (now looks like "a.b.c.d")
        }
    }
}

In C I've got this:

#include <stdio.h>
#include <malloc.h>

    int main(int argc, char* argv[])
    {
        char *formatString = "%s.%s.%s.%s";
        char *formatValues[] = {"a","b","c","d"};

        char *buffer = (char*)malloc(100 * sizeof(char));

        //This doesn't work.....
        sprintf(buffer, formatString, formatValues);

        //... buffer is junk

        return 0;
    }

How can I do this in C?

(Is there a nice function in the C standard library I can use to help me, or perhaps, is there a way to call a varargs function with an array?)

Please note, the number of arguments will never be greater than the length of the array I have. And the types will always be strings. So I might have

char *formatString = "My Formatted String %s.%s.%s";
char *formatValues[] = {"a","b","c","d","e"};

But I'll never have too few %s.

Note: the C has to work on GCC for Linux, and Visual Studio for Windows (C90).

È stato utile?

Soluzione

I don't think C provides a standardized way to do this. If you understood the internal implementation of <stdarg.h> on your system, it would probably be possible to kludge up a system-specific solution involving vprintf(3), but I have a different, conforming kludge for you...

Something that would work would involve declaring an array of some large size, set the values that you have, and then just pass every element of the array at the call site, regardless of whether they are set.

char *a[5]; // or a[50], whatever you need

// assign the elements you actually have

printf(format_string, a[0], a[1], a[2], a[3], a[4], a[5]);

Altri suggerimenti

The only type of array sprintf accepts is a null-terminated array of chars (ie a string). This should work:

#include <stdio.h>
#include <malloc.h>
int main(int argc, char* argv[])
{
    char *formatStrings[]={"%s","%s","%s","%s"};
    char *buffer= (char*)malloc(100 * sizeof(char));
    char *formatValues[]={"a","b","c","d"};
    char *endofBuffer=buffer;
    int valueCount=4;
    int i;
    for (i=0; i<valueCount; ++i)
    {
        endofBuffer+=sprintf(endofBuffer, formatStrings[i], formatValues[i]);
        if (i<valueCount-1)
            endofBuffer+=sprintf(endofBuffer, "%c", '.');
    }
    printf("%s\n",buffer);
    return 0;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top