⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sprintf.c

📁 一个操作系统,用C语言实现开发的,我在一个浙江大学的操作系统实验网站找到.大家学习以下
💻 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 + -