📄 wsprintf.c
字号:
/*****************************************************************************/
/* _PCONV_F - Perform the %f conversion */
/*****************************************************************************/
static void _pconv_f(long double cvt, _PFIELD *pfield, char **a_it)
{
/*------------------------------------------------------------------------*/
/* Local variables */
/*------------------------------------------------------------------------*/
char tmpbuf[100];
int dpt,
sign,
putdec;
/*------------------------------------------------------------------------*/
/* If no precision was specified, set it to 6. */
/*------------------------------------------------------------------------*/
if (pfield->precision < 0) pfield->precision = 6;
/*------------------------------------------------------------------------*/
/* Call the FCVT float to string function, then copy the fractional part, */
/* determine whether or not a decimal point should be placed, and copy */
/* whole number part. */
/*------------------------------------------------------------------------*/
strcpy(tmpbuf, fcvt(cvt, pfield->precision, &dpt, &sign));
_fcpy(tmpbuf, dpt, 1, pfield->precision, a_it);
putdec = (dpt != (int)strlen(tmpbuf) || _STCHK(pfield, _PFPOUND)) ? 1 : 0;
_mcpy(tmpbuf, dpt, putdec, a_it);
}
/*****************************************************************************/
/* _PCONV_E - Perform the %e conversion */
/*****************************************************************************/
static void _pconv_e(long double cvt, _PFIELD *pfield, char **a_it)
{
/*------------------------------------------------------------------------*/
/* Local variables */
/*------------------------------------------------------------------------*/
char tmpbuf[100];
int dpt,
sign,
putdec,
exp = 0;
/*------------------------------------------------------------------------*/
/* If no precision was specified, set it to 6. */
/*------------------------------------------------------------------------*/
if (pfield->precision < 0) pfield->precision = 6;
/*------------------------------------------------------------------------*/
/* Convert CVT to x.xxxe+xx form, keeping the exponent in EXP. */
/*------------------------------------------------------------------------*/
if (cvt)
{
for (;cvt < 1; cvt *= 10, exp--);
for (;cvt >= 10; cvt /= 10, exp++);
}
/*------------------------------------------------------------------------*/
/* Call the FCVT float to string function, copy the exponent part, the */
/* fractional part, then determine whether or not a decimal point should */
/* be placed, and copy the whole number part. */
/*------------------------------------------------------------------------*/
strcpy(tmpbuf, fcvt(cvt, pfield->precision, &dpt, &sign));
if (dpt==2) /* fcvt() might have rounded the number */
{
dpt--; exp++;
}
_ecpy(exp, pfield->conv, a_it);
_fcpy(tmpbuf, dpt, 1, pfield->precision, a_it);
putdec = (dpt != (int)strlen(tmpbuf) || _STCHK(pfield, _PFPOUND)) ? 1 : 0;
_mcpy(tmpbuf, dpt, putdec, a_it);
}
/*****************************************************************************/
/* _PCONV_G - Perform the %g conversion */
/*****************************************************************************/
static void _pconv_g(long double cvt, _PFIELD *pfield, char **a_it)
{
/*------------------------------------------------------------------------*/
/* Local variables */
/*------------------------------------------------------------------------*/
char tmpbuf[100];
char *check;
int dpt,
sign,
putdec,
exp = 0,
change_test = 0;
/*------------------------------------------------------------------------*/
/* If the precision was given as 0, set it to one. */
/*------------------------------------------------------------------------*/
if (pfield->precision == 0) pfield->precision = 1;
/*------------------------------------------------------------------------*/
/* If no precision was specified, set it to 6. */
/*------------------------------------------------------------------------*/
if (pfield->precision < 0) pfield->precision = 6;
strcpy(tmpbuf, ecvt((double)cvt, pfield->precision, &dpt, &sign));
/*------------------------------------------------------------------------*/
/* If the exponent is less than -4, or greater than or equal to the */
/* precision, convert the number as a %e conversion. Otherwise convert */
/* it as a %f conversion. */
/*------------------------------------------------------------------------*/
if (dpt < -3 || dpt > pfield->precision)
{
for (;dpt > 1; dpt--, exp++);
for (;dpt < 1; dpt++, exp--);
_ecpy(exp, pfield->conv-2, a_it);
}
/*------------------------------------------------------------------------*/
/* Copy the fractional part of the number. CHANGE_TEST will be set if */
/* there was a fractional part, otherwise it will remain a zero. */
/*------------------------------------------------------------------------*/
check = *a_it;
_fcpy(tmpbuf, dpt, (_STCHK(pfield, _PFPOUND)) ? 1 : 0, pfield->precision,
a_it);
change_test = (check != *a_it);
/*------------------------------------------------------------------------*/
/* If the '#' flag was used, or there was a fractional part to the number */
/* a decimal point will be placed. */
/*------------------------------------------------------------------------*/
putdec = (_STCHK(pfield, _PFPOUND) || change_test) ? 1 : 0;
_mcpy(tmpbuf, dpt, putdec, a_it);
}
/*****************************************************************************/
/* _FCPY - Copy the fraction part of a float to a string */
/*****************************************************************************/
static char *_fcpy(const char *tmpbuf, int dpt, int trail, int precision,
char **a_it)
{
/*------------------------------------------------------------------------*/
/* Local variables */
/*------------------------------------------------------------------------*/
int i;
char *tmpptr = (char *)tmpbuf + strlen(tmpbuf) -1;
/*------------------------------------------------------------------------*/
/* Fill all unused precision spaces with zeros. */
/*------------------------------------------------------------------------*/
for (i = 0; i < precision && dpt > (int)strlen(tmpbuf) && trail; i++)
*((*a_it)--) = '0';
/*------------------------------------------------------------------------*/
/* Copy the fractional part of the float into the string. */
/*------------------------------------------------------------------------*/
if (dpt < (int)strlen(tmpbuf) && dpt >= 0)
{
i = (int)strlen(tmpbuf) - dpt;
/*---------------------------------------------------------------------*/
/* Skip trailing zeros if TRAIL is not set. */
/*---------------------------------------------------------------------*/
if (! trail) for (; i > 0 && *tmpptr == '0'; tmpptr--, i--);
for (; i > 0; tmpptr--, i--) *((*a_it)--) = *tmpptr;
}
/*------------------------------------------------------------------------*/
/* Place any leading fractional zeros if necessary. */
/*------------------------------------------------------------------------*/
if (dpt < 0)
{
for (i = strlen(tmpbuf); i > 0; tmpptr--, i--) *((*a_it)--) = *tmpptr;
for (i = -dpt; i > 0; i--) *((*a_it)--) = '0';
}
return(*a_it);
}
/*****************************************************************************/
/* _ECPY - Copy the "e+xx" part of a float to a string */
/*****************************************************************************/
static char *_ecpy(int exp, char letter, char **a_it)
{
_ltostr((exp > 0) ? exp : -exp, 10, 'd', a_it);
if (exp < 10 && exp > -10) *((*a_it)--) = '0';
*((*a_it)--) = (exp < 0) ? '-' : '+';
*((*a_it)--) = letter;
return(*a_it);
}
/*****************************************************************************/
/* _MCPY - Copy the whole number part of a float to a string */
/*****************************************************************************/
static char *_mcpy(const char *tmpbuf, int dpt, int putdec, char **a_it)
{
/*------------------------------------------------------------------------*/
/* Local variables */
/*------------------------------------------------------------------------*/
int i;
char *tmpptr;
/*------------------------------------------------------------------------*/
/* If the number has both a whole number part and a fractional part, */
/* position TMPPTR to the last character of the whole number. */
/*------------------------------------------------------------------------*/
if (dpt > 0 && dpt <= (int)strlen(tmpbuf)) tmpptr = (char *)tmpbuf + dpt -1;
/*------------------------------------------------------------------------*/
/* Place a decimal point if PUTDEC is set. */
/*------------------------------------------------------------------------*/
if (putdec) *((*a_it)--) = '.';
/*------------------------------------------------------------------------*/
/* Place any whole number trailing zeros. */
/*------------------------------------------------------------------------*/
for (i = dpt; i > (int)strlen(tmpbuf); i--) *((*a_it)--) = '0';
/*------------------------------------------------------------------------*/
/* Copy the rest of the whole number. */
/*------------------------------------------------------------------------*/
if (i > 0) for (; tmpptr >= tmpbuf; tmpptr--) *((*a_it)--) = *tmpptr;
else *((*a_it)--) = '0';
return(*a_it);
}
#endif
/*--------------------------------------------------------------------------*/
/* PERFORM SAME OPERATION AS MEMCPY, ABORT IF "ch" is COPIED. */
/* RETURN POINTER TO BYTE AFTER ch IS FOUND, OR NULL IF NOT FOUND */
/*--------------------------------------------------------------------------*/
/*static unsigned short *wmemccpy(unsigned short *dest, const unsigned short *src, int ch, int count)
{
if (count <= 0) return NULL;
do
if ((*dest++ = *src++) == ch) return (dest);
while (--count != 0);
return NULL;
}*/
/*****************************************************************************/
/* _SETFIELD - Performs conversions when the '%' is encountered */
/* */
/* This function takes pfield, and calls the appropriate processing */
/* function for the conversion required in the _PFIELD structure. It */
/* returns a pointer to the result string. */
/* */
/*****************************************************************************/
static char *_setfield(_PFIELD *pfield, va_list *_ap)
{
/*------------------------------------------------------------------------*/
/* Local variable declarations, and a description of their use */
/* */
/* FLD is a temporary string that will hold the conversion. F_START */
/* will be a pointer to the beginning of the field, and if a */
/* field width was specified, F_END will be a pointer to the end of */
/* the field. This designated field is located at the beginning of */
/* the string FLD. A_END is a pointer to the end of the string FLD, */
/* and this is where the primary conversion will take place. Using */
/* A_IT, an iterator beginning at the end of FLD, the number will be */
/* written one digit at a time starting with the rightmost digit. */
/* Using the pointer WHERE, the number in string form will be moved */
/* to its appropriate place within the field after making adjustments */
/* called for by various flags in the format specification (a minus */
/* sign, leading zeros, etc.). The string FLD will then be returned. */
/* */
/* MINUS_FLAG is exactly what it says ( = 1 if number is negative). */
/* */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -