📄 printf.c
字号:
if (*lpFmt==(WCHAR)'-')
left++;
else if (*lpFmt==(WCHAR)'#')
prefix++;
else
break;
}
/* find fill character */
if (*lpFmt==(WCHAR)'0') {
fillch=(WCHAR)'0';
lpFmt++;
} else
fillch=(WCHAR)' ';
/* read the width specification */
lpFmt=SP_GetFmtValue(lpFmt,&cch, &lpParms);
width=cch;
/* read the precision */
if (*lpFmt==(WCHAR)'.') {
lpFmt=SP_GetFmtValue(++lpFmt,&cch, &lpParms);
prec=cch;
} else
prec=-1;
/* get the operand size */
size=1;
if (*lpFmt=='l') {
lpFmt++;
} else if (*lpFmt=='h') {
size=0;
lpFmt++;
} else if ((*lpFmt == 'I') && (*(lpFmt+1) == '6') && (*(lpFmt+2) == '4')) {
lpFmt+=3;
size = 2;
}
upper=0;
sign=0;
radix=10;
switch (*lpFmt) {
case 0:
goto errorout;
case (WCHAR)'i':
case (WCHAR)'d':
sign++;
case (WCHAR)'u':
/* turn off prefix if decimal */
prefix=0;
donumeric:
/* special cases to act like MSC v5.10 */
if (left || prec>=0)
fillch=(WCHAR)' ';
if (size == 1)
val.l=va_arg(lpParms, long);
else if (size == 2)
val.i64 = va_arg(lpParms, __int64);
else if (sign)
val.l=va_arg(lpParms, short);
else
val.ul=va_arg(lpParms, unsigned);
if (sign && val.l<0L)
val.l=-val.l;
else
sign=0;
lpT=lpOut;
/* blast the number backwards into the user buffer */
if (size == 2)
cch=SP_PutNumber64(lpOut,val.i64,cchLimit,radix,upper);
else
cch=SP_PutNumber(lpOut,val.l,cchLimit,radix,upper);
if (!(cchLimit-=cch))
goto errorout;
lpOut+=cch;
width-=cch;
prec-=cch;
if (prec>0)
width-=prec;
/* fill to the field precision */
while (prec-->0)
out((WCHAR)'0');
if (width>0 && !left) {
/* if we're filling with spaces, put sign first */
if (fillch!=(WCHAR)'0') {
if (sign) {
sign=0;
out((WCHAR)'-');
width--;
}
if (prefix) {
out(prefix);
out((WCHAR)'0');
prefix=0;
}
}
if (sign)
width--;
/* fill to the field width */
while (width-->0)
out(fillch);
/* still have a sign? */
if (sign)
out((WCHAR)'-');
if (prefix) {
out(prefix);
out((WCHAR)'0');
}
/* now reverse the string in place */
SP_Reverse(lpT,lpOut-1);
} else {
/* add the sign character */
if (sign) {
out((WCHAR)'-');
width--;
}
if (prefix) {
out(prefix);
out((WCHAR)'0');
}
/* reverse the string in place */
SP_Reverse(lpT,lpOut-1);
/* pad to the right of the string in case left aligned */
while (width-->0)
out(fillch);
}
break;
case (WCHAR) 'p' :
// Fall into case below, since NT is going to 64 bit
// they are starting to use p to indicate a pointer
// value. They only seem to support lower case 'p'
case (WCHAR)'X':
upper++;
case (WCHAR)'x':
radix=16;
if (prefix)
if (upper)
prefix=(WCHAR)'X';
else
prefix=(WCHAR)'x';
goto donumeric;
case (WCHAR)'c':
val.sz[0] = va_arg(lpParms, WCHAR);
val.sz[1]=0;
lpT=val.sz;
cch = 1; // Length is one character.
/* stack aligned to larger size */
goto putstring;
case 'a': // ascii string!
case 'S':
PrtAscii:
if (!(lpC=va_arg(lpParms, LPCHAR)))
lpC = "(NULL)";
cch=strlen(lpC);
if (prec>=0 && cch>prec)
cch=prec;
width -= cch;
if (left) {
while (cch--)
out((WCHAR)*lpC++);
while (width-->0)
out(fillch);
} else {
while (width-->0)
out(fillch);
while (cch--)
out((WCHAR)*lpC++);
}
break;
case 's':
if (!size)
goto PrtAscii;
if (!(lpT=va_arg(lpParms,LPWSTR)))
lpT = L"(NULL)";
cch=strlenW(lpT);
putstring:
if (prec>=0 && cch>prec)
cch=prec;
width -= cch;
if (left) {
while (cch--)
out(*lpT++);
while (width-->0)
out(fillch);
} else {
while (width-->0)
out(fillch);
while (cch--)
out(*lpT++);
}
break;
default:
out(*lpFmt); /* Output the invalid char and continue */
break;
}
} else /* character not a '%', just do it */
out(*lpFmt);
/* advance to next format string character */
lpFmt++;
}
errorout:
*lpOut=0;
return maxchars-cchLimit;
}
//------------------------------------------------------------------------------
// GetFmtValue
// reads a width or precision value from the format string
//------------------------------------------------------------------------------
LPCWSTR
SP_GetFmtValue(
LPCWSTR lpch,
int *lpw,
va_list *plpParms
)
{
int i=0;
if (*lpch == TEXT('*')) {
*lpw = va_arg(*plpParms, int);
lpch++;
} else {
while (*lpch>=(WCHAR)'0' && *lpch<=(WCHAR)'9') {
i = i*10 + (*lpch-(WCHAR)'0');
lpch++;
}
*lpw=i;
}
/* return the address of the first non-digit character */
return lpch;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void
SP_Reverse(
LPWSTR lpFirst,
LPWSTR lpLast
)
{
int swaps;
WCHAR tmp;
swaps = ((((DWORD)lpLast - (DWORD)lpFirst)/sizeof(WCHAR)) + 1)/2;
while (swaps--) {
tmp = *lpFirst;
*lpFirst++ = *lpLast;
*lpLast-- = tmp;
}
}
const WCHAR lowerval[] = TEXT("0123456789abcdef");
const WCHAR upperval[] = TEXT("0123456789ABCDEF");
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
int
SP_PutNumber(
LPWSTR lpb,
ULONG n,
int limit,
int radix,
int mycase
)
{
int used = 0;
while (limit--) {
*lpb++ = (mycase ? upperval[(n % radix)] : lowerval[(n % radix)]);
used++;
if (!(n /= radix))
break;
}
return used;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
int
SP_PutNumber64(
LPWSTR lpb,
__int64 i64,
int limit,
int radix,
int mycase
)
{
int used = 0;
while (limit--) {
*lpb++ = (mycase ? upperval[(i64 % radix)] : lowerval[(i64 % radix)]);
used++;
if (!(i64 /= radix))
break;
}
return used;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -