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

📄 snprintf.c

📁 站点映像程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*   Unix snprintf implementation.   Version 1.1      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.      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:   sitecopy changes:      renamed dtoa -> doubletoa to avoid dtoa conflict with cygwin.   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)*/#ifdef HAVE_CONFIG_H#include <config.h>#endif#include "snprintf.h"#ifdef HAVE_STRING_H#include <string.h>    /* for strlen() */#endif#ifdef HAVE_STRINGS_H#include <strings.h>#endif#ifdef HAVE_STDLIB_H#include <stdlib.h>    /* for atoi() */#endif#include <ctype.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 = doubletoa(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 = doubletoa(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++;

⌨️ 快捷键说明

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