I am writing the following code for an embedded system, where I am putting up strings and integers into a buffer. There are several sprintf
s in the code similar to the one below (with more than one strings and integers).
sprintf(txbuf, "info=>t:%d-%d-%d$%d:%d:%d", ui8Day,ui8Month, ui8Year, ui8Hour, ui8Minute, ui8Second);
PS: The $
, -
and :
are just for data seperation.
However, sprintf
has a large memory footprint and I am attempting to reduce the code size. I also tried using strcat
and strcpy
functions but they also ended up increasing the code size.
Here is a minimalist implementation of sprintf
you can use as a replacement that only supports %d
, %u
, %x
, %s
, %c
and %%
. You can easily modify it to remove unused conversion specifiers:
#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;
}
Note however that your example should probably use %02d
or %.2d
to produce 01
instead of 1
for minutes and seconds. For this purpose, you could add another conversion specifier %D
with this code:
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;
您可以使用 snprintf() 而不是 sprintf() 因为 snprintf() 停止内存溢出。
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.