📄 _printfi.c
字号:
/* structure pointed to by PFIELD. They will be needed for future */
/* reference. */
/* */
/*****************************************************************************/
static void _pproc_fwp(_PFIELD *pfield, char **it, va_list *_ap)
{
char tmpstr[10];
char *tmpptr;
/*------------------------------------------------------------------------*/
/* If a '*' was given for the field width, use the next argument as */
/* the field width for the conversion. Otherwise, copy the following */
/* numerical characters into a temporary string, and convert that */
/* string into an integer, which will be used for the field width. */
/*------------------------------------------------------------------------*/
if(**it == '*')
{
pfield->fwidth = va_arg(*_ap, int);
/*---------------------------------------------------------------------*/
/* If the argument given for the field width is negative, treat it as */
/* if the '-' flag was used, and the field width was positive. */
/*---------------------------------------------------------------------*/
if(pfield->fwidth < 0)
{
pfield->fwidth = -(pfield->fwidth);
_SET(pfield, _PFMINUS);
}
(*it)++;
}
else
{
/*---------------------------------------------------------------------*/
/* Initialize the temporary string and iterator that will hold the */
/* field width temporarily. */
/*---------------------------------------------------------------------*/
tmpptr = tmpstr;
memset(tmpptr, '\0', 10);
while((**it >= '0') && (**it <= '9')) *(tmpptr++) = *((*it)++);
if(*tmpstr != '\0') pfield->fwidth = atoi(tmpstr);
}
/*------------------------------------------------------------------------*/
/* If a '.' appears as the next character, process the following */
/* characters as a precision. */
/*------------------------------------------------------------------------*/
if(**it == '.')
{
(*it)++;
/*---------------------------------------------------------------------*/
/* If a '*' was given for the precision, use the next argument as */
/* the precision for the conversion. Otherwise, copy the following */
/* numerical characters into a temporary string, and convert that */
/* string into an integer, which will be used for the precision. */
/*---------------------------------------------------------------------*/
if(**it == '*')
{
pfield->precision = va_arg(*_ap, int);
(*it)++;
}
else
{
/*------------------------------------------------------------------*/
/* Initialize the temporary string and iterator that will hold */
/* the field width temporarily. */
/*------------------------------------------------------------------*/
tmpptr = tmpstr;
memset(tmpptr, '\0', 10);
while((**it >= '0') && (**it <= '9')) *(tmpptr++) = *((*it)++);
if(*tmpstr != '\0') pfield->precision = atoi(tmpstr);
else pfield->precision = 0;
}
}
return;
}
/*****************************************************************************/
/* _PPROC_STR - Processes the string conversion (%s) */
/* */
/* This function places all or a portion of the input string into the */
/* the temporary string. It returns a zero, unless the input string had */
/* a length of zero. In this case, a one is returned. */
/* */
/*****************************************************************************/
static void _pproc_str(_PFIELD *pfield, void *_op, va_list *_ap, int *count,
int (*_outs)(char *, void *))
{
/*------------------------------------------------------------------------*/
/* Local variables */
/*------------------------------------------------------------------------*/
char *strbuf;
char tmpstr[80+1];
char *tmpptr;
int len, buflen;
/*------------------------------------------------------------------------*/
/* Get the next argument. */
/*------------------------------------------------------------------------*/
strbuf = va_arg(*_ap, char*);
/*------------------------------------------------------------------------*/
/* Handle NULL strings. */
/*------------------------------------------------------------------------*/
if(strbuf == NULL)
{
_outs("(null)", _op);
return;
}
buflen = (pfield->precision >= 0 && pfield->precision < strlen(strbuf)) ?
pfield->precision : strlen(strbuf);
len = (pfield->fwidth > buflen) ? pfield->fwidth : buflen;
if (len > 80) len = 80;
*count += len;
tmpptr = tmpstr;
if(buflen < len && !_STCHK(pfield, _PFMINUS))
{
memset(tmpptr, ' ', (len - buflen));
tmpptr += (len - buflen);
}
strncpy(tmpptr, strbuf, buflen);
tmpptr += buflen;
if(buflen < len && _STCHK(pfield, _PFMINUS))
{
memset(tmpptr, ' ', (len - buflen));
tmpptr += (len - buflen);
}
*(tmpstr + len) = '\0';
_outs(tmpstr, _op);
return;
}
/*****************************************************************************/
/* _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 void _setfield(char *fld, _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). */
/* */
/*------------------------------------------------------------------------*/
char *f_start = (char *)fld;
char *f_end = f_start + pfield->fwidth;
char *a_end = f_start + _ARSIZE -1;
char *a_it = a_end;
char *where;
int minus_flag = 0;
int plus_flag = 0;
/*------------------------------------------------------------------------*/
/* Initialize the temporary string. Then, since we are working from */
/* right to left, begin with the NULL character. */
/*------------------------------------------------------------------------*/
memset(fld, ' ', _ARSIZE);
*(a_it--) = '\0';
/*------------------------------------------------------------------------*/
/* Call the appropriate processing function. */
/*------------------------------------------------------------------------*/
switch(pfield->conv)
{
case 'd' :
case 'i' :
case 'o' :
case 'u' :
case 'x' :
case 'X' :
case 'p' : _pproc_diouxp(pfield, &minus_flag, &a_it, _ap);
break;
#ifndef NOFLOAT
case 'g' :
case 'G' :
case 'e' :
case 'E' :
case 'f' : _pproc_fge(pfield, &minus_flag, &a_it, _ap);
break;
#endif
case 'c' : *(a_it--) = va_arg(*_ap, int);
_UNSET(pfield, _PFPLUS);
break;
case '%' : strcpy(f_start, "%");
}
plus_flag = (_STCHK(pfield, _PFPLUS) && SIGNED_CONV);
/*------------------------------------------------------------------------*/
/* If the number was negative, or the '+' flag was used, insert the sign. */
/* Make sure unsigned conversions don't get a '+' sign. */
/*------------------------------------------------------------------------*/
if (minus_flag) *(a_it--) = '-';
else if (plus_flag) *(a_it--) = '+';
/*------------------------------------------------------------------------*/
/* If the number was positive, the '+' flag was not used, and the ' ' */
/* flag was used, insert a space. */
/*------------------------------------------------------------------------*/
if(! minus_flag && ! plus_flag && _STCHK(pfield, _PFSPACE)) *(a_it--) = ' ';
/*------------------------------------------------------------------------*/
/* If the '-' flag was used or the resulting string is larger than the */
/* field, left justify the result in the array. Otherwise right-justify */
/* it. */
/*------------------------------------------------------------------------*/
where = (_STCHK(pfield, _PFMINUS) ||
((a_end - a_it) > pfield->fwidth)) ? f_start :
(f_end - (a_end - a_it)+1);
a_it = (char *)memccpy(where, a_it+1, '\0', _ARSIZE);
/*------------------------------------------------------------------------*/
/* If a resulting left-justified string is smaller than the field width, */
/* move the terminating NULL character to the end of the field. */
/*------------------------------------------------------------------------*/
if(a_it <= f_end)
{
memset(a_it - 1, ' ', f_end - a_it + 1);
*f_end = '\0';
}
/*------------------------------------------------------------------------*/
/* If the '0' flag was used, and the resulting string is right-justified, */
/* fill in the leading zeros. */
/*------------------------------------------------------------------------*/
if(_STCHK(pfield, _PFZERO))
{
memset(f_start, '0', (where - f_start));
/*---------------------------------------------------------------------*/
/* Make sure any sign or leading space is moved to the left side of */
/* any leading zeros. */
/*---------------------------------------------------------------------*/
if((minus_flag || plus_flag || _STCHK(pfield, _PFSPACE)) &&
where != f_start)
{
*f_start = *where;
*where = '0';
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -