精简版sprintf适合嵌入式使用
生活随笔
收集整理的這篇文章主要介紹了
精简版sprintf适合嵌入式使用
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
支持格式化duxXcspo,并支持控制符+-.0,有測試代碼
人狠話不多,直接上代碼。
#include <stdint.h> #include <stdarg.h>#define FORMAT_ALIGN_RIGHT 0 //默認右對齊 #define FORMAT_ALIGN_LEFT 1 //左對齊 '-' #define FORMAT_SIGN_FLAG 2 //強制正負數符號 '+' #define FORMAT_PADDING_ZERO 4 //填充0代替空格 '0'static int print(char **out, int ch) {int count = 1;if (ch == '\n')count += print(out, '\r');if (out)*(*out)++ = ch;elseputchar(ch);return count; }static int prints(char **out, const char *str, int flags, int minW, int maxW) {int pad = flags & FORMAT_PADDING_ZERO ? '0' : ' ';int len = 0, padLen = 0;const char *ptr;int ret = 0;//字符串長度for (ptr = str; *ptr; ++ptr)len++;//max修正if (maxW < minW)maxW = minW;if (len < minW){//需要填充padLen = minW - len;}//需要填充 pad 字符if (!(flags & FORMAT_ALIGN_LEFT)){//不是左對齊,先填充for (; padLen > 0; padLen--){ret += print(out, pad);}}//輸出字符串while (*str){if (maxW && ret == maxW){//字符串已達規定最大長度break;}ret += print(out, *str++);}//如果是左對齊,那么 padLen 應該是非0for (; padLen > 0; padLen--){ret += print(out, pad);}return ret; }static int printi(char **out, int val, int sign, int base, int alphaBase, int flags, int minW, int maxW) {unsigned int uval = (unsigned int)val;char buf[32], *ptr;int neg = 0, len = 0;int forceSign = flags & FORMAT_SIGN_FLAG;int padZero = flags & FORMAT_PADDING_ZERO;if (sign){if (val < 0){neg = 1;uval = (unsigned int)-val;}}ptr = buf + sizeof(buf) - 1;*ptr = '\0';while (uval){int t = uval % base;if (t >= 10)t += alphaBase - '0' - 10;*--ptr = t + '0';uval /= base;len++;}if (forceSign || neg)len++;if (padZero && len < minW){int padLen = minW - len;int padMax = sizeof(buf) - len - 1;if (padLen > padMax)padLen = padMax;while (padLen--)*--ptr = '0';}if (neg)*--ptr = '-';else if (forceSign)*--ptr = '+';return prints(out, ptr, flags, minW, maxW); }static int vprintf_internal(char *buf, const char *fmt, va_list va) {char *dst = buf;char **out = buf ? &dst : NULL;int count = 0;while (*fmt){if (*fmt == '%'){int flags = 0, minW = 0, maxW = 0;int type, waitMin = 0, waitMax = 0;char *str, tmp[2];fmt++;while (1){type = *fmt++;if (!type)break;switch (type){case '%':goto _out;case '-':flags |= FORMAT_ALIGN_LEFT;break;case '+':flags |= FORMAT_SIGN_FLAG;break;case '.':waitMax = 1;break;case '0':if (!waitMin && !waitMax){flags |= FORMAT_PADDING_ZERO;waitMin = 1;}else{goto _num;}break;case '1': case '2': case '3': case '4': case '5':case '6': case '7': case '8': case '9': _num:if (!waitMin && !waitMax){waitMin = 1;}if (waitMin){minW = minW * 10 + type - '0';}else if(waitMax){maxW = maxW * 10 + type - '0';}break;case 'd': case 'u': case 'x': case 'X':case 'c': case 's': case 'p': case 'o':goto _format;default:goto _out;}}_format:switch (type){case 'o':count += printi(out, va_arg(va, int), 0, 8, 'A', flags, minW, maxW);break;case 'd':count += printi(out, va_arg(va, int), 1, 10, 'A', flags, minW, maxW);break;case 'u':count += printi(out, va_arg(va, int), 0, 10, 'A', flags, minW, maxW);break;case 'x':count += printi(out, va_arg(va, int), 0, 16, 'a', flags, minW, maxW);break;case 'X':count += printi(out, va_arg(va, int), 0, 16, 'A', flags, minW, maxW);break;case 'c':tmp[0] = (char)va_arg(va, int);tmp[1] = 0;count += prints(out, tmp, flags, minW, maxW);break;case 's':str = va_arg(va, char *);str = str ? str : "(null)";count += prints(out, str, flags, minW, maxW);break;case 'p':count += prints(out, "0x", 0, 0, 0);count += printi(out, va_arg(va, int), 0, 16, 'A', FORMAT_PADDING_ZERO, 8, 0);break;}continue;}else{ _out:count += print(out, *fmt);}fmt++;}if (out)**out = '\0';va_end(va);return count; }int printf(const char *fmt, ...) {va_list va;va_start(va, fmt);return vprintf_internal(0, fmt, va); }int vsprintf(char *buf, const char *fmt, va_list va) {return vprintf_internal(buf, fmt, va); }int sprintf(char *buf, const char *fmt, ...) {va_list va;va_start(va, fmt);return vprintf_internal(buf, fmt, va); }void ShowBinary(void *buf, int len) {int i = 0;unsigned char *p = (unsigned char *)buf;while (len){i++;printf("%02X ", (int)p[0]);if ((i % 16) == 0)printf("\n");p++;len--;}printf("\n"); }int main(int argc, char *argv[]) {printf("a=[%s]\n", "0123456789");printf("a=[%12s]\n", "0123456789");printf("a=[%-12s]\n", "0123456789");printf("a=[%.12s]\n\n", "01234567890123456789");printf("a=[%d]\n", 0xFFFFFFFF);printf("a=[%u]\n", 0xFFFFFFFF);printf("a=[%+u]\n\n", 0xFFFFFFFF);printf("a=[%15d]\n", 0xFFFFFFFF);printf("a=[%-15d]\n", 0xFFFFFFFF);printf("a=[%+-15d]\n", 0xFFFFFFFF);printf("a=[%015d]\n", 0xFFFFFFFF);printf("a=[%-015d]\n", 0xFFFFFFFF);printf("a=[%+-015d]\n\n", 0xFFFFFFFF);printf("a=[%15u]\n", 0xFFFFFFFF);printf("a=[%-15u]\n", 0xFFFFFFFF);printf("a=[%+-15u]\n", 0xFFFFFFFF);printf("a=[%015u]\n", 0xFFFFFFFF);printf("a=[%-015u]\n", 0xFFFFFFFF);printf("a=[%+-015u]\n\n", 0xFFFFFFFF);printf("a=[%15x]\n", 0xFFFFFFFF);printf("a=[%-15x]\n", 0xFFFFFFFF);printf("a=[%+-15x]\n", 0xFFFFFFFF);printf("a=[%015x]\n", 0xFFFFFFFF);printf("a=[%-015x]\n", 0xFFFFFFFF);printf("a=[%+-015x]\n\n", 0xFFFFFFFF);printf("a=[%15X]\n", 0xFFFFFFFF);printf("a=[%-15X]\n", 0xFFFFFFFF);printf("a=[%+-15X]\n", 0xFFFFFFFF);printf("a=[%015X]\n", 0xFFFFFFFF);printf("a=[%-015X]\n", 0xFFFFFFFF);printf("a=[%+-015X]\n\n", 0xFFFFFFFF);printf("a=[%15o]\n", 0xFFFFFFFF);printf("a=[%-15o]\n", 0xFFFFFFFF);printf("a=[%+-15o]\n", 0xFFFFFFFF);printf("a=[%015o]\n", 0xFFFFFFFF);printf("a=[%-015o]\n", 0xFFFFFFFF);printf("a=[%+-015o]\n\n", 0xFFFFFFFF);getch();return 0; }代碼重構自?https://bbs.csdn.net/topics/397124846
總結
以上是生活随笔為你收集整理的精简版sprintf适合嵌入式使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: GCC和MSVC的INITIALIZER
- 下一篇: 重写了GD32VF103的启动脚本和链接