HOME
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdarg.h>
int format(char* s, size_t n, const char* format, ...)
{
const char* arg[10] = { 0 };
_Static_assert(sizeof(arg) / sizeof(arg[0]) == 10, "0-9");
va_list args;
va_start(args, format);
const char* p = format;
while (*p)
{
if (*p == '%' && (*(p + 1) != '%'))
{
p++;
int index = (*p - '0');
if (index >= 0 && index <= 9)
{
if (arg[index] == 0)
{
arg[index] = va_arg(args, char*);
printf("SET %d = %s\n", index, arg[index]);
}
}
}
p++;
}
va_end(args);
p = format;
int count = 0;
while (*p)
{
if (*p == '%')
{
p++; //skip %
if (*p >= '0' && *p <= '9')
{
int index = (*p - '0');
const char* from = arg[index];
if (from == NULL)
{
from = "???";
}
while (from && *from)
{
if (count < n - 1)
{
s[count] = *from;
}
count++;
from++;
}
p++;
}
else if (*p == '%')
{
if (count < n - 1)
{
s[count] = *p;
}
count++;
p++;
}
else
{
/*error?*/
}
}
else
{
if (count < n - 1)
{
s[count] = *p;
}
count++;
p++;
}
}
if (count < n)
{
s[count] = 0;
}
else
{
if (n > 0)
s[n - 1] = 0;
}
return count;
}
int main()
{
printf("A %1$s B %2$s C %1$s", "ONE", "TWO");
char buffer[50];
int n = format(buffer, sizeof buffer, "A %% %1", "ONE");
assert(strcmp(buffer, "A % ONE") == 0);
assert(n == 7);
n = format(buffer, sizeof buffer, "A %0 B %1 C %0", "ONE", "TWO");
assert(n == 17);
assert(strcmp(buffer, "A ONE B TWO C ONE") == 0);
char buffer3[3];
n = format(buffer3, sizeof buffer3, "%0", "ABC");
assert(n == 3);
assert(strcmp(buffer3, "AB") == 0);
}