Вот минималистская реализация sprintf
, которую вы можете использовать в качестве замены, которая поддерживает только %d
, %u
, %x
, %s
, %c
и %%
. Вы можете легко изменить его, удалив неиспользуемые спецификаторы преобразования:
#include <limits.h>
#include <stdarg.h>
#include <stdio.h>
int small_sprintf(char *dest, const char *fmt, ...) {
char buf[20];
va_list arg;
char *p, *s;
int n;
unsigned int u;
va_start(arg, fmt);
for (p = dest; (*p++ = *fmt++) != '\0';) {
if (fmt[-1] == '%' && *fmt != '\0') {
p--;
s = buf + sizeof(buf);
*--s = '\0';
switch (*fmt++) {
case 'u':
u = va_arg(arg, unsigned);
goto conv10;
case 'd':
u = n = va_arg(arg, int);
if (n < 0) {
*p++ = '-';
u = -u;
}
conv10:
do { *--s = '0' + (u % 10); } while ((u /= 10) != 0);
break;
case 'x':
u = va_arg(arg, unsigned);
do { *--s = "0123456789abcdef"[u & 15]; } while ((u >>= 4) != 0);
break;
case 's':
s = va_arg(arg, char *);
break;
case 'c':
*--s = (char)va_arg(arg, int);
break;
default:
*--s = fmt[-1];
break;
}
while ((*p = *s++) != '\0')
p++;
}
}
va_end(arg);
return p - 1 - dest;
}
int main() {
char buf[128];
int n = small_sprintf(buf, "Hello %s%c %d %d%% INT_MIN=%d, INT_MAX=%x", "world", '!', 0, 100, INT_MIN, INT_MAX);
puts(buf);
while (n-- > 0)
putchar('-');
putchar('\n');
return 0;
}
Обратите внимание, однако, что в вашем примере, вероятно, следует использовать %02d
или %.2d
для получения 01
вместо 1
для минут и секунд. Для этого вы можете добавить еще один спецификатор преобразования %D
с этим кодом:
case 'D': // convert an unsigned integer as 2 decimal digits
d = va_arg(arg, unsigned);
*--s = '0' + u % 10;
*--s = '0' + u / 10 % 10;
break;