📄 output.c
字号:
else
/* malloc failed, cap precision further */
precision = BUFFERSIZE - CVTBUFSIZE;
}
#if !LONGDOUBLE_IS_DOUBLE
/* do the conversion */
if (flags & FL_LONGDOUBLE) {
LONGDOUBLE tmp;
tmp=va_arg(argptr, LONGDOUBLE);
/* Note: assumes ch is in ASCII range */
_cldcvt(&tmp, text.sz, (char)ch, precision, capexp);
} else
#endif /* !LONGDOUBLE_IS_DOUBLE */
{
DOUBLE tmp;
tmp=va_arg(argptr, DOUBLE);
/* Note: assumes ch is in ASCII range */
_cfltcvt(&tmp,text.sz, (char)ch, precision, capexp);
}
/* '#' and precision == 0 means force a decimal point */
if ((flags & FL_ALTERNATE) && precision == 0)
_forcdecpt(text.sz);
/* 'g' format means crop zero unless '#' given */
if (ch == _T('g') && !(flags & FL_ALTERNATE))
_cropzeros(text.sz);
/* check if result was negative, save '-' for later */
/* and point to positive part (this is for '0' padding) */
if (*text.sz == '-') {
flags |= FL_NEGATIVE;
++text.sz;
}
textlen = strlen(text.sz); /* compute length of text */
}
break;
case _T('d'):
case _T('i'):
/* signed decimal output */
flags |= FL_SIGNED;
radix = 10;
goto COMMON_INT;
case _T('u'):
radix = 10;
goto COMMON_INT;
case _T('p'):
/* write a pointer -- this is like an integer or long */
/* except we force precision to pad with zeros and */
/* output in big hex. */
precision = 2 * sizeof(void *); /* number of hex digits needed */
#if !PTR_IS_INT
flags |= FL_LONG; /* assume we're converting a long */
#endif /* !PTR_IS_INT */
/* DROP THROUGH to hex formatting */
case _T('X'):
/* unsigned upper hex output */
hexadd = _T('A') - _T('9') - 1; /* set hexadd for uppercase hex */
goto COMMON_HEX;
case _T('x'):
/* unsigned lower hex output */
hexadd = _T('a') - _T('9') - 1; /* set hexadd for lowercase hex */
/* DROP THROUGH TO COMMON_HEX */
COMMON_HEX:
radix = 16;
if (flags & FL_ALTERNATE) {
/* alternate form means '0x' prefix */
prefix[0] = _T('0');
prefix[1] = (TCHAR)(_T('x') - _T('a') + _T('9') + 1 + hexadd); /* 'x' or 'X' */
prefixlen = 2;
}
goto COMMON_INT;
case _T('o'):
/* unsigned octal output */
radix = 8;
if (flags & FL_ALTERNATE) {
/* alternate form means force a leading 0 */
flags |= FL_FORCEOCTAL;
}
/* DROP THROUGH to COMMON_INT */
COMMON_INT: {
/* This is the general integer formatting routine. */
/* Basically, we get an argument, make it positive */
/* if necessary, and convert it according to the */
/* correct radix, setting text and textlen */
/* appropriately. */
#if _INTEGRAL_MAX_BITS >= 64
unsigned __int64 number; /* number to convert */
int digit; /* ascii value of digit */
__int64 l; /* temp long value */
#else /* _INTEGRAL_MAX_BITS >= 64 */
unsigned long number; /* number to convert */
int digit; /* ascii value of digit */
long l; /* temp long value */
#endif /* _INTEGRAL_MAX_BITS >= 64 */
/* 1. read argument into l, sign extend as needed */
#if _INTEGRAL_MAX_BITS >= 64
if (flags & FL_I64)
l = get_int64_arg(&argptr);
else
#endif /* _INTEGRAL_MAX_BITS >= 64 */
#if !LONG_IS_INT
if (flags & FL_LONG)
l = get_long_arg(&argptr);
else
#endif /* !LONG_IS_INT */
#if !SHORT_IS_INT
if (flags & FL_SHORT) {
if (flags & FL_SIGNED)
l = (short) get_int_arg(&argptr); /* sign extend */
else
l = (unsigned short) get_int_arg(&argptr); /* zero-extend*/
} else
#endif /* !SHORT_IS_INT */
{
if (flags & FL_SIGNED)
l = get_int_arg(&argptr); /* sign extend */
else
l = (unsigned int) get_int_arg(&argptr); /* zero-extend*/
}
/* 2. check for negative; copy into number */
if ( (flags & FL_SIGNED) && l < 0) {
number = -l;
flags |= FL_NEGATIVE; /* remember negative sign */
} else {
number = l;
}
#if _INTEGRAL_MAX_BITS >= 64
if ( (flags & FL_I64) == 0 ) {
/*
* Unless printing a full 64-bit value, insure values
* here are not in cananical longword format to prevent
* the sign extended upper 32-bits from being printed.
*/
number &= 0xffffffff;
}
#endif /* _INTEGRAL_MAX_BITS >= 64 */
/* 3. check precision value for default; non-default */
/* turns off 0 flag, according to ANSI. */
if (precision < 0)
precision = 1; /* default precision */
else {
flags &= ~FL_LEADZERO;
if (precision > MAXPRECISION)
precision = MAXPRECISION;
}
/* 4. Check if data is 0; if so, turn off hex prefix */
if (number == 0)
prefixlen = 0;
/* 5. Convert data to ASCII -- note if precision is zero */
/* and number is zero, we get no digits at all. */
text.sz = &buffer.sz[BUFFERSIZE-1]; /* last digit at end of buffer */
while (precision-- > 0 || number != 0) {
digit = (int)(number % radix) + '0';
number /= radix; /* reduce number */
if (digit > '9') {
/* a hex digit, make it a letter */
digit += hexadd;
}
*text.sz-- = (char)digit; /* store the digit */
}
textlen = (char *)&buffer.sz[BUFFERSIZE-1] - text.sz; /* compute length of number */
++text.sz; /* text points to first digit now */
/* 6. Force a leading zero if FORCEOCTAL flag set */
if ((flags & FL_FORCEOCTAL) && (text.sz[0] != '0' || textlen == 0)) {
*--text.sz = '0';
++textlen; /* add a zero */
}
}
break;
}
/* At this point, we have done the specific conversion, and */
/* 'text' points to text to print; 'textlen' is length. Now we */
/* justify it, put on prefixes, leading zeros, and then */
/* print it. */
if (!no_output) {
int padding; /* amount of padding, negative means zero */
if (flags & FL_SIGNED) {
if (flags & FL_NEGATIVE) {
/* prefix is a '-' */
prefix[0] = _T('-');
prefixlen = 1;
}
else if (flags & FL_SIGN) {
/* prefix is '+' */
prefix[0] = _T('+');
prefixlen = 1;
}
else if (flags & FL_SIGNSP) {
/* prefix is ' ' */
prefix[0] = _T(' ');
prefixlen = 1;
}
}
/* calculate amount of padding -- might be negative, */
/* but this will just mean zero */
padding = fldwidth - textlen - prefixlen;
/* put out the padding, prefix, and text, in the correct order */
if (!(flags & (FL_LEFT | FL_LEADZERO))) {
/* pad on left with blanks */
WRITE_MULTI_CHAR(_T(' '), padding, &charsout);
}
/* write prefix */
WRITE_STRING(prefix, prefixlen, &charsout);
if ((flags & FL_LEADZERO) && !(flags & FL_LEFT)) {
/* write leading zeros */
WRITE_MULTI_CHAR(_T('0'), padding, &charsout);
}
/* write text */
#ifndef _UNICODE
if (bufferiswide && (textlen > 0)) {
wchar_t *p;
int retval, count;
char buffer[MB_LEN_MAX+1];
p = text.wz;
count = textlen;
while (count--) {
retval = wctomb(buffer, *p++);
if (retval <= 0)
break;
WRITE_STRING(buffer, retval, &charsout);
}
} else {
WRITE_STRING(text.sz, textlen, &charsout);
}
#else /* _UNICODE */
if (!bufferiswide && textlen > 0) {
char *p;
int retval, count;
p = text.sz;
count = textlen;
while (count-- > 0) {
retval = mbtowc(&wchar, p, MB_CUR_MAX);
if (retval <= 0)
break;
WRITE_CHAR(wchar, &charsout);
p += retval;
}
} else {
WRITE_STRING(text.wz, textlen, &charsout);
}
#endif /* _UNICODE */
if (flags & FL_LEFT) {
/* pad on right with blanks */
WRITE_MULTI_CHAR(_T(' '), padding, &charsout);
}
/* we're done! */
}
if (heapbuf) {
_free_crt(heapbuf);
heapbuf = NULL;
}
break;
}
}
return charsout; /* return value = number of characters written */
}
/*
* Future Optimizations for swprintf:
* - Don't free the memory used for converting the buffer to wide chars.
* Use realloc if the memory is not sufficient. Free it at the end.
*/
/***
*void write_char(int ch, int *pnumwritten)
*ifdef _UNICODE
*void write_char(wchar_t ch, FILE *f, int *pnumwritten)
*endif
*void write_char(int ch, FILE *f, int *pnumwritten)
*
*Purpose:
* Writes a single character to the given file/console. If no error occurs,
* then *pnumwritten is incremented; otherwise, *pnumwritten is set
* to -1.
*
*Entry:
* int ch - character to write
* FILE *f - file to write to
* int *pnumwritten - pointer to integer to update with total chars written
*
*Exit:
* No return value.
*
*Exceptions:
*
*******************************************************************************/
#ifdef CPRFLAG
LOCAL(void) write_char (
int ch,
int *pnumwritten
)
{
if (_putch_lk(ch) == EOF)
*pnumwritten = -1;
else
++(*pnumwritten);
}
#elif defined (_UNICODE)
LOCAL(void) write_char (
wchar_t ch,
FILE *f,
int *pnumwritten
)
{
if (_putwc_lk(ch, f) == WEOF)
*pnumwritten = -1;
else
++(*pnumwritten);
}
#else /* defined (_UNICODE) */
LOCAL(void) write_char (
int ch,
FILE *f,
int *pnumwritten
)
{
if (_putc_lk(ch, f) == EOF)
*pnumwritten = -1;
else
++(*pnumwritten);
}
#endif /* defined (_UNICODE) */
/***
*void write_multi_char(int ch, int num, int *pnumwritten)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -