📄 sprintf.c
字号:
// System Utility Library for application
#include <string.h>
#include <stdarg.h>
#include <sys/sysutils.h>
static int copystr(char *buf, const char *src, char fill, int width, unsigned int max_len)
{
int i, j, l = strlen(src);
width-=l;
if(width<0) width=0;
if(fill)
{
j = 0;
for(i=0; i<width && max_len; i++){ *buf++=fill; max_len--; j++; }
if((unsigned int)l>max_len) l=(int)max_len;
strncpy(buf, src, l);
return j+l;
}
else
{
if((unsigned int)l>max_len) l = (int)max_len;
strncpy(buf, src, l);
max_len-=l; buf+=l;
for(i=0; i<width && max_len; i++){ *buf++=' '; max_len--; l++; }
return l;
}
}
static int formatstr(char *buf, int len, unsigned int max_len, va_list *pargs)
{
va_list var;
char fill = 0, type;
int width = 0, i = 1, j;
char text[32];
char *ptr, ch;
int val;
if(buf[i] == '-'){ fill = ' '; i++; }
else if(buf[i] == '0'){ fill = '0'; i++; }
for(; i<len-1; i++)
if(buf[i]>='0' && buf[i]<='9')
width = width * 10 + buf[i] - '0';
type = buf[len-1];
var = *pargs;
switch(type)
{
case 's':
ptr = va_arg(var, char*);
break;
case 'x':
case 'X':
val = va_arg(var, int);
j = -1;
for(i=0; i<8; i++)
{
ch = (char)((val>>((7-i)*4))&0x0f);
text[i] = ch >= 10 ? ch - 10 + (type=='x'?'a':'A') : (ch + '0');
if(j==-1 && (text[i]!='0' || i==7)) j = i;
}
text[8]=0;
ptr = text+j;
break;
case 'u':
case 'd':
val = va_arg(var, int);
j = 0;
if(type=='d' && val<0)
{
j = '-';
val = -val;
}
text[0]=0; i=0;
while(val)
{
text[i++]=(char)(((unsigned int)val)%10+'0');
val/=10;
}
if(!text[0]) text[i++]='0';
if(j) text[i++]=j;
text[i]=0;
for(j=0; j<i/2; j++)
{ ch = text[j]; text[j] = text[i-j-1]; text[i-j-1] = ch; }
ptr = text;
break;
case 'c':
text[0] = va_arg(var, char);
text[1] = 0;
ptr = text;
break;
default:
return len;
}
*pargs = var;
return copystr(buf, ptr, fill, width, max_len);
}
unsigned int _knsprnt(char *buf, unsigned int n, const char *fmt, va_list ap)
{
int status;
unsigned int oldcount, count;
char *oldbuf;
enum { stNext, stPercent, stForType, stForWidth, stWidthOrType };
#define SAVEBUF() (oldbuf=buf, oldcount=count)
#define ADDCHAR(ch) (*buf=(char)(ch), buf++, count++)
#define STATUS(st) (status = (st))
#define ISTYPE(ch) (strchr("sxXduc", (char)(ch)) != NULL)
#define FORMAT() count = formatstr(oldbuf, buf-oldbuf, n-oldcount, &ap); \
buf = oldbuf+count; count = oldcount+count;
count = 0;
STATUS(stNext);
while(*fmt)
{
switch(status)
{
case stNext:
switch(*fmt)
{
case '%':
SAVEBUF();
ADDCHAR(*fmt);
STATUS(stPercent);
break;
default:
ADDCHAR(*fmt);
}
break;
case stPercent:
switch(*fmt)
{
case '%':
STATUS(stNext);
break;
case '0': // Fill with zero
ADDCHAR(*fmt);
STATUS(stForWidth);
break;
case '-': // Fill with space(right align)
ADDCHAR(*fmt);
STATUS(stForWidth);
break;
default:
ADDCHAR(*fmt);
if(*fmt>='1' && *fmt<='9')
STATUS(stWidthOrType);
else if(ISTYPE(*fmt))
{
FORMAT();
STATUS(stNext);
}
else // Syntax error
STATUS(stNext);
}
break;
case stForWidth:
ADDCHAR(*fmt);
if(*fmt>='1' && *fmt<='9')
STATUS(stWidthOrType);
else // Syntax error
STATUS(stNext);
break;
case stWidthOrType:
ADDCHAR(*fmt);
if(*fmt>='0' && *fmt<='9')
{} // Do nothing
else if(ISTYPE(*fmt)) // Done!
{
FORMAT();
STATUS(stNext);
}
else // Syntax error
STATUS(stNext);
break;
case stForType:
if(ISTYPE(*fmt)) // Done!
{
FORMAT();
STATUS(stNext);
}
else // Syntax error
STATUS(stNext);
break;
}
fmt++;
}
*buf = 0;
return count;
}
int nsprintf(char *buf, int len, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
return (int)_knsprnt(buf, (unsigned int)(len<0?-1:len), fmt, args);
}
int sprintf(char *buf, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
return (int)_knsprnt(buf, (unsigned int)-1, fmt, args);
}
int vsprintf(char *buf, const char *fmt, va_list args)
{
return (int)_knsprnt(buf, (unsigned int)-1, fmt, args);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -