|
发表于 2019-4-29 14:50:30
|
显示全部楼层
在github.com找到一个简化:
- // mini-printf.h
- #ifndef __MINI_PRINTF__
- #define __MINI_PRINTF__
- #ifdef __cplusplus
- extern "C" {
- #endif
- #include <stdarg.h>
- int mini_vsnprintf(char* buffer, unsigned int buffer_len, const char *fmt, va_list va);
- int mini_snprintf(char* buffer, unsigned int buffer_len, const char *fmt, ...);
- #ifdef __cplusplus
- }
- #endif
- #define vsnprintf mini_vsnprintf
- #define snprintf mini_snprintf
- #endif
复制代码
- #include "mini-printf.h"
- static unsigned int
- mini_strlen(const char *s)
- {
- unsigned int len = 0;
- while (s[len] != '\0') len++;
- return len;
- }
- static unsigned int
- mini_itoa(int value, unsigned int radix, unsigned int uppercase, unsigned int unsig,
- char *buffer, unsigned int zero_pad)
- {
- char *pbuffer = buffer;
- int negative = 0;
- unsigned int i, len;
- /* No support for unusual radixes. */
- if (radix > 16)
- return 0;
- if (value < 0 && !unsig) {
- negative = 1;
- value = -value;
- }
- /* This builds the string back to front ... */
- do {
- int digit = value % radix;
- *(pbuffer++) = (digit < 10 ? '0' + digit : (uppercase ? 'A' : 'a') + digit - 10);
- value /= radix;
- } while (value > 0);
- for (i = (pbuffer - buffer); i < zero_pad; i++)
- *(pbuffer++) = '0';
- if (negative)
- *(pbuffer++) = '-';
- *(pbuffer) = '\0';
- /* ... now we reverse it (could do it recursively but will
- * conserve the stack space) */
- len = (pbuffer - buffer);
- for (i = 0; i < len / 2; i++) {
- char j = buffer[i];
- buffer[i] = buffer[len-i-1];
- buffer[len-i-1] = j;
- }
- return len;
- }
- struct mini_buff {
- char *buffer, *pbuffer;
- unsigned int buffer_len;
- };
- static int
- _putc(int ch, struct mini_buff *b)
- {
- if ((unsigned int)((b->pbuffer - b->buffer) + 1) >= b->buffer_len)
- return 0;
- *(b->pbuffer++) = ch;
- *(b->pbuffer) = '\0';
- return 1;
- }
- static int
- _puts(char *s, unsigned int len, struct mini_buff *b)
- {
- unsigned int i;
- if (b->buffer_len - (b->pbuffer - b->buffer) - 1 < len)
- len = b->buffer_len - (b->pbuffer - b->buffer) - 1;
- /* Copy to buffer */
- for (i = 0; i < len; i++)
- *(b->pbuffer++) = s[i];
- *(b->pbuffer) = '\0';
- return len;
- }
- int
- mini_vsnprintf(char *buffer, unsigned int buffer_len, const char *fmt, va_list va)
- {
- struct mini_buff b;
- char bf[24];
- char ch;
- b.buffer = buffer;
- b.pbuffer = buffer;
- b.buffer_len = buffer_len;
- while ((ch=*(fmt++))) {
- if ((unsigned int)((b.pbuffer - b.buffer) + 1) >= b.buffer_len)
- break;
- if (ch!='%')
- _putc(ch, &b);
- else {
- char zero_pad = 0;
- char *ptr;
- unsigned int len;
- ch=*(fmt++);
- /* Zero padding requested */
- if (ch=='0') {
- ch=*(fmt++);
- if (ch == '\0')
- goto end;
- if (ch >= '0' && ch <= '9')
- zero_pad = ch - '0';
- ch=*(fmt++);
- }
- switch (ch) {
- case 0:
- goto end;
- case 'u':
- case 'd':
- len = mini_itoa(va_arg(va, unsigned int), 10, 0, (ch=='u'), bf, zero_pad);
- _puts(bf, len, &b);
- break;
- case 'x':
- case 'X':
- len = mini_itoa(va_arg(va, unsigned int), 16, (ch=='X'), 1, bf, zero_pad);
- _puts(bf, len, &b);
- break;
- case 'c' :
- _putc((char)(va_arg(va, int)), &b);
- break;
- case 's' :
- ptr = va_arg(va, char*);
- _puts(ptr, mini_strlen(ptr), &b);
- break;
- default:
- _putc(ch, &b);
- break;
- }
- }
- }
- end:
- return b.pbuffer - b.buffer;
- }
- int
- mini_snprintf(char* buffer, unsigned int buffer_len, const char *fmt, ...)
- {
- int ret;
- va_list va;
- va_start(va, fmt);
- ret = mini_vsnprintf(buffer, buffer_len, fmt, va);
- va_end(va);
- return ret;
- }
复制代码
链接:https://github.com/mludvig/mini-printf |
|