2024年C C++最新C语言printf函数是怎么解析格式化字符串的?_fioformatv,程序员经验分享

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

int		realsz;		/* field size expanded by dprec */

#ifdef _WRS_ALTIVEC_SUPPORT
FAST int i; /* handy integer (short term usage) /
FAST char * vp; /
handy char pointer (short term usage) /
char Separator; /
separator for vector elements /
char C_Separator; /
separator for char vector elements /
VECTOR vec; /
vector argument /
BOOL doVector; /
AltiVec vector /
#endif /
_WRS_ALTIVEC_SUPPORT /
char FMT[20]; /
To collect fmt info /
FAST char * Collect; /
char pointer to FMT */

BOOL	doLongInt;	/* long integer */
BOOL	doLongLongInt;	/* long long integer - 64 bit */
BOOL	doShortInt;	/* short integer */
BOOL	doAlt;		/* alternate form */
BOOL	doLAdjust;	/* left adjustment */
BOOL	doZeroPad;	/* zero (as opposed to blank) pad */
BOOL	doHexPrefix;	/* add 0x or 0X prefix */
BOOL	doSign;		/* change sign to '-' */
char	buf[BUF];	/* space for %c, %[diouxX], %[eEfgG] */

#if (CPU_FAMILY != AM29XXX)
char ox[2]; /* space for 0x hex-prefix /
#else
char ox[3]; /
space for 0x hex-prefix /
#endif /
(CPU_FAMILY != AM29XXX)/
char * xdigs = NULL; /
digits for [xX] conversion /
int ret = 0; /
return value accumulator /
enum {OCT, DEC, HEX} base; /
base for [diouxX] conversion */

FOREVER		/* Scan the format for conversions (`%' character) */
{
for (cp = CHAR_FROM_CONST(fmt);((ch=*fmt) != EOS)&&(ch != '%'); fmt++)
    ;

if ((n = fmt - cp) != 0)
    {
    if ((*outRoutine) (cp, n, outarg) != OK)
	return (ERROR);

    ret += n;
    }

if (ch == EOS)
    return (ret);		/* return total length */

fmt++;				/* skip over '%' */

#ifdef _WRS_ALTIVEC_SUPPORT
Separator = ’ '; /* the default separator for vector elements /
C_Separator = EOS; /
the default separator for char vector elements /
doVector = FALSE; /
no vector modifier /
#endif /
_WRS_ALTIVEC_SUPPORT */

*FMT		= EOS;
Collect		= FMT;
doLongInt	= FALSE;	/* long integer */
doLongLongInt	= FALSE;	/* 64 bit integer */
doShortInt	= FALSE;	/* short integer */
doAlt		= FALSE;	/* alternate form */
doLAdjust	= FALSE;	/* left adjustment */
doZeroPad	= FALSE;	/* zero (as opposed to blank) pad */
doHexPrefix	= FALSE;	/* add 0x or 0X prefix */
doSign		= FALSE;	/* change sign to '-' */
dprec		= 0;
fpprec		= 0;
width		= 0;
prec		= -1;
oldprec		= -1;
sign		= EOS;

#ifdef _WRS_E500_FIXED_POINT_SUPPORT
e500_sign_flag = 1; /* default is %r – signed fixed point value /
#endif /
_WRS_E500_FIXED_POINT_SUPPORT */

#define get_CHAR (ch = *Collect++ = *fmt++)

#ifdef _WRS_ALTIVEC_SUPPORT
#define SET_VECTOR_FMT(VFMT,NO)
do
{
char * to;

vec.vul = va_arg (vaList,__vector unsigned long);
cp = buf;

*Collect = EOS;
i = (NO);
to = VFMT = (char ) malloc (i20);
while(i-- > 0) {

char * from = FMT;

*to++ = ‘%’;
while (*to++ = *from++);
(char)((int)(to)-1) = Separator;
}
*(–to) = EOS;
}
while (0)

#define RESET_VECTOR_FMT(VFMT)

size = strlen(cp);
sign = EOS;

free(VFMT)
#endif /* _WRS_ALTIVEC_SUPPORT */

rflag:
get_CHAR;
reswitch:
switch (ch)
{
case ’ ':
/* If the space and + flags both appear, the space
* flag will be ignored. – ANSI X3J11
/
if (!sign)
sign = ’ ‘;
goto rflag;
#ifdef WRS_ALTIVEC_SUPPORT
case ‘,’:
case ‘;’:
case ‘:’:
case '
’:
Collect–;
Separator = C_Separator = ch;
goto rflag;
#endif /
_WRS_ALTIVEC_SUPPORT */
case ‘#’:
doAlt = TRUE;
goto rflag;

    case '*':
	    /* A negative field width argument is taken as a
	     * flag followed by a positive field width.
	     *	-- ANSI X3J11
	     * They don't exclude field widths read from args.
	     */
	    if ((width = va_arg(vaList, int)) >= 0)
		goto rflag;

	    width = -width;			/* FALLTHROUGH */

    case '-':
	    doLAdjust = TRUE;
	    goto rflag;

    case '+':
	    sign = '+';
	    goto rflag;

    case '.':
	    get_CHAR;
	    if ( ch == '*' ) 
		{
		n = va_arg(vaList, int);
		prec = (n < 0) ? -1 : n;
		goto rflag;
		}

	    n = 0;
	    while (is_digit(ch)) 
		{
		n = 10 * n + to_digit(ch);
		get_CHAR;
		}
	    prec = n < 0 ? -1 : n;
	    goto reswitch;

    case '0':
	    /* Note that 0 is taken as a flag, not as the
	     * beginning of a field width. -- ANSI X3J11
	     */
	    doZeroPad = TRUE;
	    goto rflag;

    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
	    n = 0;
	    do 
		{
		n = 10 * n + to_digit(ch);
		get_CHAR;
		} while (is_digit(ch));

	    width = n;
	    goto reswitch;

    case 'h':
	    doShortInt = TRUE;
	    goto rflag;

    case 'l':
	    get_CHAR;
	    if ( ch == 'l' )
		{
		doLongLongInt = TRUE;
		goto rflag;
		}

#ifdef _WRS_E500_FIXED_POINT_SUPPORT
else if ( ch == ‘r’ || ch == ‘R’ ) /* e500 fixed point /
{
doLongLongInt = TRUE;
goto reswitch;
}
#endif /
_WRS_E500_FIXED_POINT_SUPPORT /
else
{
doLongInt = TRUE;
goto reswitch;
}
#ifdef _WRS_E500_FIXED_POINT_SUPPORT
case ‘R’: /
e500 fixed point /
e500_sign_flag = 0; /
unsigned fixed point value /
/
FALLTHROUGH /
case ‘r’: /
e500 fixed point */
sign = EOS;
cp = buf;

	    if (e500_sign_flag) {
	        ulongLongVal = SARG();
	        if ((long long)ulongLongVal < 0) 
		   {
		   ulongLongVal = -ulongLongVal;
		   sign = '-';
	 	   }
	    }
	    else ulongLongVal = UARG();

	    if (doShortInt) {
	        ndigs = 5;
	        ulongLongVal <<= (32+16);		
	    } else if (!(doLongLongInt)) {
	        ndigs = 10;
		ulongLongVal <<= 32;
	    } else {
	        ndigs = 19;
	    }
	    n = 0;
	    if (e500_sign_flag) {
	      if (ulongLongVal & (1LL << 63)) {
		n = 1;
	      }
	      ulongLongVal <<= 1;
	      ndigs--;
	    }
	    *cp++ = n + '0';
	    *cp++ = '.';
	    ndigs = (prec >0 ? prec : ndigs);
	    llconst = ((1LL << (64-1))-1);
	    while (ndigs) {
	      a = (ulongLongVal >> (64-3)) + (ulongLongVal >> (64-1)) ;
	      ulongLongVal  = (ulongLongVal & llconst) + ((ulongLongVal << 2) & llconst);
	      a += (ulongLongVal >> 63);
	      *cp++ = a + '0';
	      ndigs--;
	      ulongLongVal <<= 1;
	    }	
	    *cp = '\0';

	    cp = buf;
	    size = strlen(cp);
	    break;

#endif /* _WRS_E500_FIXED_POINT_SUPPORT */

#ifdef _WRS_ALTIVEC_SUPPORT
case ‘v’:
Collect–;
doVector = TRUE;
goto rflag;
#endif /* _WRS_ALTIVEC_SUPPORT */

    case 'c':

#ifdef _WRS_ALTIVEC_SUPPORT
if (doVector)
{
vec.vul = va_arg (vaList,__vector unsigned long);
cp = buf;
vp = (unsigned char *)&vec.u8;
i = 15;

		while(i-- > 0) {
		
			*cp++ = *vp++;
			if (C_Separator) *cp++ = C_Separator;
		}
		
		*cp++ = *vp++;

		cp = buf;
		size = 16 + (C_Separator ? 15:0);
		sign = EOS;
	    }
	    else 
	    {

#endif /* _WRS_ALTIVEC_SUPPORT */
(cp = buf) = va_arg(vaList, int);
size = 1;
sign = EOS;
#ifdef _WRS_ALTIVEC_SUPPORT
}
#endif /
_WRS_ALTIVEC_SUPPORT */
break;

    case 'D':
	    doLongInt = TRUE; 			/* FALLTHROUGH */

    case 'd':
    case 'i':

#ifdef _WRS_ALTIVEC_SUPPORT
if (doVector)
{
SET_VECTOR_FMT(vp,doShortInt?8:4);

		if (doShortInt)
			sprintf(cp,vp,vec.s16[0],vec.s16[1],vec.s16[2],vec.s16[3],
				      vec.s16[4],vec.s16[5],vec.s16[6],vec.s16[7]);
		else
			sprintf(cp,vp,vec.s32[0],vec.s32[1],vec.s32[2],vec.s32[3]);
		
		RESET_VECTOR_FMT(vp);
		break;
	    }

#endif /* _WRS_ALTIVEC_SUPPORT */

	    ulongLongVal = SARG();
	    if ((long long)ulongLongVal < 0) 
		{
		ulongLongVal = -ulongLongVal;
		sign = '-';
		}
	    base = DEC;
	    goto number;

    case 'n':
	    /* ret is int, so effectively %lln = %ln */
	    if (doLongLongInt)
		*va_arg(vaList, long long *) = (long long) ret;
	    else if (doLongInt)
		*va_arg(vaList, long *) = ret;
	    else if (doShortInt)
		*va_arg(vaList, short *) = ret;
	    else
		*va_arg(vaList, int *) = ret;
	    continue;				/* no output */

    case 'O':
	    doLongInt = TRUE;			/* FALLTHROUGH */

    case 'o':

#ifdef _WRS_ALTIVEC_SUPPORT
if (doVector)
{
SET_VECTOR_FMT(vp,doShortInt?8:4);

		if (doShortInt)
			sprintf(cp,vp,vec.s16[0],vec.s16[1],vec.s16[2],vec.s16[3],
				      vec.s16[4],vec.s16[5],vec.s16[6],vec.s16[7]);
		else
			sprintf(cp,vp,vec.s32[0],vec.s32[1],vec.s32[2],vec.s32[3]);
		
		RESET_VECTOR_FMT(vp);
		break;
	    }

#endif /* _WRS_ALTIVEC_SUPPORT */
ulongLongVal = UARG();
base = OCT;
goto nosign;

    case 'p':
	    /* The argument shall be a pointer to void.  The
	     * value of the pointer is converted to a sequence
	     * of printable characters, in an implementation
	     * defined manner. -- ANSI X3J11
	     */

#ifdef _WRS_ALTIVEC_SUPPORT
if (doVector)
{
SET_VECTOR_FMT(vp,4);

		sprintf(cp,vp,vec.u32[0],vec.u32[1],vec.u32[2],vec.u32[3]);
		
		RESET_VECTOR_FMT(vp);
		break;
	    }

#endif /* _WRS_ALTIVEC_SUPPORT */
ulongLongVal = (unsigned long long) (unsigned int)
va_arg(vaList, void );/ NOSTRICT */
base = HEX;
xdigs = “0123456789abcdef”;
doHexPrefix = TRUE;
ch = ‘x’;
goto nosign;

    case 's':
	    if ((cp = va_arg(vaList, char *)) == NULL)
		cp = "(null)";

	    if (prec >= 0) 
		{
		/* can't use strlen; can only look for the
		 * NUL in the first `prec' characters, and
		 * strlen() will go further.
		 */

		char *p = (char *)memchr(cp, 0, prec);

		if (p != NULL) 
		    {
		    size = p - cp;
		    if (size > prec)
			size = prec;
		    }
		else
		    size = prec;
		}
	    else
		size = strlen(cp);

	    sign = EOS;
	    break;

    case 'U':
	    doLongInt = TRUE;			/* FALLTHROUGH */

    case 'u':

#ifdef _WRS_ALTIVEC_SUPPORT
if (doVector)
{
SET_VECTOR_FMT(vp,doShortInt?8:4);

		if (doShortInt)
			sprintf(cp,vp,vec.u16[0],vec.u16[1],vec.u16[2],vec.u16[3],
				      vec.u16[4],vec.u16[5],vec.u16[6],vec.u16[7]);
		else
			sprintf(cp,vp,vec.u32[0],vec.u32[1],vec.u32[2],vec.u32[3]);
		
		RESET_VECTOR_FMT(vp);
		break;
	    }

#endif /* _WRS_ALTIVEC_SUPPORT */
ulongLongVal = UARG();
base = DEC;
goto nosign;

    case 'X':
	    xdigs = "0123456789ABCDEF";
	    goto hex;

    case 'x':
	    xdigs = "0123456789abcdef";

hex:
#ifdef _WRS_ALTIVEC_SUPPORT
if (doVector)
{
SET_VECTOR_FMT(vp,doShortInt?8:4);

		if (doShortInt)
			sprintf(cp,vp,vec.s16[0],vec.s16[1],vec.s16[2],vec.s16[3],
				      vec.s16[4],vec.s16[5],vec.s16[6],vec.s16[7]);
		else
			sprintf(cp,vp,vec.s32[0],vec.s32[1],vec.s32[2],vec.s32[3]);
		
		RESET_VECTOR_FMT(vp);

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

,
vec.s16[4],vec.s16[5],vec.s16[6],vec.s16[7]);
else
sprintf(cp,vp,vec.s32[0],vec.s32[1],vec.s32[2],vec.s32[3]);

		RESET_VECTOR_FMT(vp);

[外链图片转存中…(img-fzKxSt9Z-1715548747766)]
[外链图片转存中…(img-GP9Pkih0-1715548747766)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值