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

📄 snprintf.c

📁 压缩包中包含LINUX下多个命令的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*   Unix snprintf implementation.   Version 1.3   This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2 of the License, or   (at your option) any later version.   It can be redistribute also under the terms of GNU Library General   Public Lincense.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.   Revision History:   1.3:      *  add #include <config.h> ifdef HAVE_CONFIG_H      *  cosmetic change, when exponent is 0 print xxxE+00         instead of xxxE-00   1.2:      *  put the program under LGPL.   1.1:      *  added changes from Miles Bader      *  corrected a bug with %f      *  added support for %#g      *  added more comments :-)   1.0:      *  supporting must ANSI syntaxic_sugars   0.0:      *  suppot %s %c %d THANKS(for the patches and ideas):     Miles Bader     Cyrille Rustom     Jacek Slabocewiz     Mike Parker(mouse)*/#include "snprintf.h"/* * Find the nth power of 10 */PRIVATE double#ifdef __STDC__pow_10(int n)#elsepow_10(n)int n;#endif{  int i;  double P;  if (n < 0)    for (i = 1, P = 1., n = -n ; i <= n ; i++) {P *= .1;}  else    for (i = 1, P = 1. ; i <= n ; i++) {P *= 10.0;}  return P;}/* * Find the integral part of the log in base 10 * Note: this not a real log10()         I just need and approximation(integerpart) of x in:          10^x ~= r * log_10(200) = 2; * log_10(250) = 2; */PRIVATE int#ifdef __STDC__log_10(double r)#elselog_10(r)double r;#endif{  int i = 0;  double result = 1.;  if (r < 0.)    r = -r;  if (r < 1.) {    while (result >= r) {result *= .1; i++;}    return (-i);  } else {    while (result <= r) {result *= 10.; i++;}    return (i - 1);  }}/* * This function return the fraction part of a double * and set in ip the integral part. * In many ways it resemble the modf() found on most Un*x */PRIVATE double#ifdef __STDC__integral(double real, double * ip)#elseintegral(real, ip)double real;double * ip;#endif{  int j;  double i, s, p;  double real_integral = 0.;/* take care of the obvious *//* equal to zero ? */  if (real == 0.) {    *ip = 0.;    return (0.);  }/* negative number ? */  if (real < 0.)    real = -real;/* a fraction ? */  if ( real < 1.) {    *ip = 0.;    return real;  }/* the real work :-) */  for (j = log_10(real); j >= 0; j--) {    p = pow_10(j);    s = (real - real_integral)/p;    i = 0.;    while (i + 1. <= s) {i++;}    real_integral += i*p;  }  *ip = real_integral;  return (real - real_integral);}#define PRECISION 1.e-6/* * return an ascii representation of the integral part of the number * and set fract to be an ascii representation of the fraction part * the container for the fraction and the integral part or staticly * declare with fix size */PRIVATE char *#ifdef __STDC__numtoa(double number, int base, int precision, char ** fract)#elsenumtoa(number, base, precision, fract)double number;int base;int precision;char ** fract;#endif{  register int i, j;  double ip, fp; /* integer and fraction part */  double fraction;  int digits = MAX_INT - 1;  static char integral_part[MAX_INT];  static char fraction_part[MAX_FRACT];  double sign;  int ch;/* taking care of the obvious case: 0.0 */  if (number == 0.) {    integral_part[0] = '0';    integral_part[1] = '\0';    fraction_part[0] = '0';    fraction_part[1] = '\0';    return integral_part;  }/* for negative numbers */  if ((sign = number) < 0.) {    number = -number;    digits--; /* sign consume one digit */  }  fraction = integral(number, &ip);  number = ip;/* do the integral part */  if ( ip == 0.) {    integral_part[0] = '0';    i = 1;  } else {    for ( i = 0; i < digits && number != 0.; ++i) {      number /= base;      fp = integral(number, &ip);      ch = (int)((fp + PRECISION)*base); /* force to round */      integral_part[i] = (ch <= 9) ? ch + '0' : ch + 'a' - 10;      if (! isxdigit(integral_part[i])) /* bail out overflow !! */        break;      number = ip;     }  }/* Oh No !! out of bound, ho well fill it up ! */  if (number != 0.)    for (i = 0; i < digits; ++i)      integral_part[i] = '9';/* put the sign ? */  if (sign < 0.)    integral_part[i++] = '-';  integral_part[i] = '\0';/* reverse every thing */  for ( i--, j = 0; j < i; j++, i--)    SWAP_INT(integral_part[i], integral_part[j]);/* the fractionnal part */  for (i=0, fp=fraction; precision > 0 && i < MAX_FRACT ; i++, precision--	) {    fraction_part[i] = (int)((fp + PRECISION)*10. + '0');    if (! isdigit(fraction_part[i])) /* underflow ? */      break;    fp = (fp*10.0) - (double)(long)((fp + PRECISION)*10.);  }  fraction_part[i] = '\0';  if (fract != (char **)0)    *fract = fraction_part;  return integral_part;}/* for %d and friends, it puts in holder * the representation with the right padding */PRIVATE void#ifdef __STDC__decimal(struct DATA *p, double d)#elsedecimal(p, d)struct DATA *p;double d;#endif{  char *tmp;  tmp = itoa(d);  p->width -= strlen(tmp);  PAD_RIGHT(p);  PUT_PLUS(d, p);  PUT_SPACE(d, p);  while (*tmp) { /* the integral */    PUT_CHAR(*tmp, p);    tmp++;  }  PAD_LEFT(p);}/* for %o octal representation */PRIVATE void#ifdef __STDC__octal(struct DATA *p, double d)#elseoctal(p, d)struct DATA *p;double d;#endif{  char *tmp;  tmp = otoa(d);  p->width -= strlen(tmp);  PAD_RIGHT(p);  if (p->square == FOUND) /* had prefix '0' for octal */    PUT_CHAR('0', p);  while (*tmp) { /* octal */    PUT_CHAR(*tmp, p);    tmp++;  }  PAD_LEFT(p);}/* for %x %X hexadecimal representation */PRIVATE void#ifdef __STDC__hexa(struct DATA *p, double d)#elsehexa(p, d)struct DATA *p;double d;#endif{  char *tmp;  tmp = htoa(d);  p->width -= strlen(tmp);  PAD_RIGHT(p);  if (p->square == FOUND) { /* prefix '0x' for hexa */    PUT_CHAR('0', p); PUT_CHAR(*p->pf, p);  }  while (*tmp) { /* hexa */    PUT_CHAR((*p->pf == 'X' ? toupper(*tmp) : *tmp), p);    tmp++;  }  PAD_LEFT(p);}/* %s strings */PRIVATE void#ifdef __STDC__strings(struct DATA *p, char *tmp)#elsestrings(p, tmp)struct DATA *p;char *tmp;#endif{  int i;  i = strlen(tmp);  if (p->precision != NOT_FOUND) /* the smallest number */    i = (i < p->precision ? i : p->precision);  p->width -= i;  PAD_RIGHT(p);  while (i-- > 0) { /* put the sting */    PUT_CHAR(*tmp, p);    tmp++;  }  PAD_LEFT(p);}/* %f or %g  floating point representation */PRIVATE void#ifdef __STDC__floating(struct DATA *p, double d)#elsefloating(p, d)struct DATA *p;double d;#endif{  char *tmp, *tmp2;  int i;  DEF_PREC(p);  d = ROUND(d, p);  tmp = dtoa(d, p->precision, &tmp2);  /* calculate the padding. 1 for the dot */  p->width = p->width -            ((d > 0. && p->justify == RIGHT) ? 1:0) -            ((p->space == FOUND) ? 1:0) -            strlen(tmp) - p->precision - 1;  PAD_RIGHT(p);  PUT_PLUS(d, p);  PUT_SPACE(d, p);  while (*tmp) { /* the integral */    PUT_CHAR(*tmp, p);    tmp++;  }  if (p->precision != 0 || p->square == FOUND)    PUT_CHAR('.', p);  /* put the '.' */  if (*p->pf == 'g' || *p->pf == 'G') /* smash the trailing zeros */    for (i = strlen(tmp2) - 1; i >= 0 && tmp2[i] == '0'; i--)       tmp2[i] = '\0';  for (; *tmp2; tmp2++)    PUT_CHAR(*tmp2, p); /* the fraction */  PAD_LEFT(p);}/* %e %E %g exponent representation */PRIVATE void#ifdef __STDC__exponent(struct DATA *p, double d)#elseexponent(p, d)struct DATA *p;double d;#endif{  char *tmp, *tmp2;  int j, i;  DEF_PREC(p);  j = log_10(d);  d = d / pow_10(j);  /* get the Mantissa */  d = ROUND(d, p);  tmp = dtoa(d, p->precision, &tmp2);  /* 1 for unit, 1 for the '.', 1 for 'e|E',   * 1 for '+|-', 3 for 'exp' */  /* calculate how much padding need */  p->width = p->width -             ((d > 0. && p->justify == RIGHT) ? 1:0) -             ((p->space == FOUND) ? 1:0) - p->precision - 7;  PAD_RIGHT(p);  PUT_PLUS(d, p);  PUT_SPACE(d, p);  while (*tmp) {/* the integral */    PUT_CHAR(*tmp, p);    tmp++;  }  if (p->precision != 0 || p->square == FOUND)    PUT_CHAR('.', p);  /* the '.' */  if (*p->pf == 'g' || *p->pf == 'G') /* smash the trailing zeros */    for (i = strlen(tmp2) - 1; i >= 0 && tmp2[i] == '0'; i--)       tmp2[i] = '\0';  for (; *tmp2; tmp2++)    PUT_CHAR(*tmp2, p); /* the fraction */  if (*p->pf == 'g' || *p->pf == 'e') { /* the exponent put the 'e|E' */

⌨️ 快捷键说明

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