⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 _printfi.c

📁 MMI层OBJ不能完全编译
💻 C
📖 第 1 页 / 共 4 页
字号:
   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


/*****************************************************************************/
/* _PPROC_DIOUXP   -  Process the conversion for d, i, o, u, x, and p        */
/*                                                                           */
/*    This function takes the structure PFIELD, which contains all of the    */
/*    flags and parameters to process the conversion, and it does this       */
/*    conversion, and stores the result in the string pointed to by          */
/*    *A_IT.                                                                 */
/*                                                                           */
/*****************************************************************************/
static int _pproc_diouxp(_PFIELD *pfield, int *minus_flag, char **a_it, 
                         va_list *_ap)
{
   /*------------------------------------------------------------------------*/
   /* Local variables                                                        */
   /*------------------------------------------------------------------------*/
   int digits =  0;
   int base   = 10;
   uintmax_t cvt;

   /*------------------------------------------------------------------------*/
   /* If no precision was given, set it to 1.                                */
   /*------------------------------------------------------------------------*/
   if(pfield->precision < 0) pfield->precision = 1; 
   else                      _UNSET(pfield, _PFZERO);

   /*------------------------------------------------------------------------*/
   /* Set the base of the number by the type of conversion specified.        */
   /*------------------------------------------------------------------------*/
   switch(pfield->conv)
   {
      case 'p' :
      case 'x' :
      case 'X' :  base = 16;
                  break;

      case 'o' :  base = 8;
                  break;

      default  :
      case 'u' :
      case 'd' :
      case 'i' :  base = 10;
  	          break;
   }  

   /*------------------------------------------------------------------------*/
   /* Get the next argument.                                                 */
   /*------------------------------------------------------------------------*/
   cvt = _getarg_diouxp(pfield, _ap);

   /*------------------------------------------------------------------------*/
   /* If the precision is 0, and the number is 0, do nothing and return 1.   */
   /*------------------------------------------------------------------------*/
   if(pfield->precision == 0 && cvt == 0) return 1;

   /*------------------------------------------------------------------------*/
   /* If the number is signed and negative, set the minus sign flag, and     */
   /* negate the number.                                                     */
   /*------------------------------------------------------------------------*/
   if((pfield->conv == 'd' || pfield->conv == 'i')
      && ((intmax_t)cvt < 0))
   {
      *minus_flag = 1;
      cvt = -(intmax_t)cvt;
   }

   /*------------------------------------------------------------------------*/
   /* Call the function to convert the number to a string, and add the       */
   /* total number of digits assigned into DIGITS.                           */
   /*------------------------------------------------------------------------*/
   digits += _ltostr(cvt, base, pfield->conv, a_it);

   /*------------------------------------------------------------------------*/
   /* Fill in the remainder of the precision with zeros.                     */
   /*------------------------------------------------------------------------*/
   while(digits++ < pfield->precision) *((*a_it)--) = '0';


   /*------------------------------------------------------------------------*/
   /* If the "#" flag was used in the X or x conversion, prefix a "0x" or    */
   /* "0X" to the hexadecimal number.                                        */
   /*------------------------------------------------------------------------*/
   if((pfield->conv == 'x' || pfield->conv == 'X') && _STCHK(pfield, _PFPOUND))
   {
      *((*a_it)--) = pfield->conv;
      *((*a_it)--) = '0';
   }

   /*------------------------------------------------------------------------*/
   /* If the "#' flag was used in the o conversion, prefix a "0" to the      */
   /* octal number.                                                          */
   /*------------------------------------------------------------------------*/
   if(pfield->conv == 'o' && _STCHK(pfield, _PFPOUND)) *((*a_it)--) = '0';

   return (0);

}


/*****************************************************************************/
/* _GETARG_DIOUXP -  Get the argument for a d, i, o, u, x, or p conversion   */
/*                                                                           */
/*    This function takes the next argument off the argument list, after     */
/*    determining what kind of argument it is.  It decides this by checking  */
/*    to see if the 'h' or the 'l' flag was used.  It returns the next       */
/*    argument.                                                              */
/*****************************************************************************/
static uintmax_t _getarg_diouxp(_PFIELD *pfield, va_list *_ap)
{
   /*------------------------------------------------------------------------*/
   /* Local variables                                                        */
   /*------------------------------------------------------------------------*/
   uintmax_t cvt = 0;

   if (pfield->conv == 'p') cvt = (uintmax_t)va_arg(*_ap, void *);
   else
   /*------------------------------------------------------------------------*/
   /* Get the number from the next argument.  Determine what kind of         */
   /* argument by checking for the h or l flag in the format specification.  */
   /*------------------------------------------------------------------------*/
   switch(_STCHK(pfield, (_MFH | _MFL | _MFLL)))
   {
      case _MFH   :  switch(pfield->conv)
                     {
                        case 'd' :
                        case 'i' : 
			    cvt = va_arg(*_ap, int);
			    break;
			    
                        case 'o' :
                        case 'u' :
                        case 'x' :
                        case 'X' : 
			    cvt = (unsigned short) va_arg(*_ap, unsigned int);
                     }
                     break;

      case _MFL   :  switch(pfield->conv)
                     {
                        case 'd' :
                        case 'i' : 
			    cvt = va_arg(*_ap, long int);
			    break;

                        case 'o' :
                        case 'u' :
                        case 'x' :
                        case 'X' : 
			    cvt = va_arg(*_ap, unsigned long int);
                     }
                     break;
#ifdef LLONG_MAX
      case _MFLL  :  switch(pfield->conv)
                     {
                        case 'd' :
                        case 'i' : 
			    cvt = va_arg(*_ap, long long int);
			    break;

                        case 'o' :
                        case 'u' :
                        case 'x' :
                        case 'X' : 
			    cvt = va_arg(*_ap, unsigned long long int);
                     }
                     break;
#endif   
      default     :  switch(pfield->conv)
                     {
                        case 'd' :
                        case 'i' : 
			    cvt = va_arg(*_ap, int);
			    break;
 
                        case 'o' :
                        case 'u' :
                        case 'x' :
                        case 'X' :
			    cvt = va_arg(*_ap, unsigned int);
                     }
   }

   return (cvt);
}


/*****************************************************************************/
/* _LTOSTR  -  Convert an integer to a string of up to base 16               */
/*                                                                           */
/*    This function takes an uintmax_t integer, converts it to a string      */
/*    which is pointed to by *A_IT.  The result will also be converted to    */
/*    a base corresponding to the variable base.                             */
/*                                                                           */
/*****************************************************************************/
static int _ltostr(uintmax_t cvt, int base, char conv, char **a_it)
{
   /*------------------------------------------------------------------------*/
   /* Local Variables                                                        */
   /*------------------------------------------------------------------------*/
   uintmax_t  quot,
              rem;
       char  *bnum = "0123456789abcdef0123456789ABCDEF";

   /*------------------------------------------------------------------------*/
   /* The number CVT will be converted to a string by taking the remainder   */
   /* of a division of it by its base, and converting it to a character.     */
   /* The number CVT is then set equal to itself divided by its base, and    */
   /* this continues until CVT is 0.                                         */
   /*------------------------------------------------------------------------*/

   if(! cvt) *((*a_it)--) = '0';

   while(cvt)
   {
      quot = _div(cvt, base);
      rem = cvt - (quot * base);

      if(conv == 'X') rem += 16;

      *((*a_it)--) = bnum[rem];
      cvt = quot;
   }

   return (strlen(*a_it) - 1);
}


/*****************************************************************************/
/* _DIV  -  Divide two integers                                              */
/*                                                                           */
/*    This function takes a uintmax_t, and divides it by an integer.         */
/*    Division must take place in unsigned arithmetic, because signed '/'    */
/*    can overflow.  This function is used by _LTOSTR when it is converting  */
/*    an unsigned int to a string.                                           */
/*                                                                           */
/*****************************************************************************/
static uintmax_t _div(uintmax_t cvt, int base)
{
    /*-----------------------------------------------------------------------*/
    /* Use shifts to optimize power-of-two bases                             */
    /*-----------------------------------------------------------------------*/
    switch(base)
    {
	case  8: return cvt >> 3;
	case 16: return cvt >> 4;
    }

    /*-----------------------------------------------------------------------*/
    /* Perform divide in narrowest arithmetic possible, for speed.	     */
    /*-----------------------------------------------------------------------*/
         if (cvt < UINT_MAX)  return (unsigned int)cvt / base;
    else if (cvt < ULONG_MAX) return (unsigned long)cvt / base;
    else return cvt / base;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -