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

📄 snprintf.c

📁 ccache 是一个快速的编译器缓存。当您编译一个程序的时候
💻 C
📖 第 1 页 / 共 2 页
字号:
	}	if (flags & DP_F_MINUS) 		spadlen = -spadlen; /* Left Justifty */#ifdef DEBUG_SNPRINTF	printf("zpad: %d, spad: %d, min: %d, max: %d, place: %d\n",	       zpadlen, spadlen, min, max, place);#endif	/* Spaces */	while (spadlen > 0) {		dopr_outch (buffer, currlen, maxlen, ' ');		--spadlen;	}	/* Sign */	if (signvalue) 		dopr_outch (buffer, currlen, maxlen, signvalue);	/* Zeros */	if (zpadlen > 0) {		while (zpadlen > 0) {			dopr_outch (buffer, currlen, maxlen, '0');			--zpadlen;		}	}	/* Digits */	while (place > 0) 		dopr_outch (buffer, currlen, maxlen, convert[--place]);  	/* Left Justified spaces */	while (spadlen < 0) {		dopr_outch (buffer, currlen, maxlen, ' ');		++spadlen;	}}static LDOUBLE abs_val(LDOUBLE value){	LDOUBLE result = value;	if (value < 0)		result = -value;		return result;}static LDOUBLE POW10(int exp){	LDOUBLE result = 1;		while (exp) {		result *= 10;		exp--;	}  	return result;}static LLONG ROUND(LDOUBLE value){	LLONG intpart;	intpart = (LLONG)value;	value = value - intpart;	if (value >= 0.5) intpart++;		return intpart;}/* a replacement for modf that doesn't need the math library. Should   be portable, but slow */static double my_modf(double x0, double *iptr){	int i;	long l;	double x = x0;	double f = 1.0;	for (i=0;i<100;i++) {		l = (long)x;		if (l <= (x+1) && l >= (x-1)) break;		x *= 0.1;		f *= 10.0;	}	if (i == 100) {		/* yikes! the number is beyond what we can handle. What do we do? */		(*iptr) = 0;		return 0;	}	if (i != 0) {		double i2;		double ret;		ret = my_modf(x0-l*f, &i2);		(*iptr) = l*f + i2;		return ret;	} 	(*iptr) = l;	return x - (*iptr);}static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,		   LDOUBLE fvalue, int min, int max, int flags){	int signvalue = 0;	double ufvalue;	char iconvert[311];	char fconvert[311];	int iplace = 0;	int fplace = 0;	int padlen = 0; /* amount to pad */	int zpadlen = 0; 	int caps = 0;	int index;	double intpart;	double fracpart;	double temp;  	/* 	 * AIX manpage says the default is 0, but Solaris says the default	 * is 6, and sprintf on AIX defaults to 6	 */	if (max < 0)		max = 6;	ufvalue = abs_val (fvalue);	if (fvalue < 0) {		signvalue = '-';	} else {		if (flags & DP_F_PLUS) { /* Do a sign (+/i) */			signvalue = '+';		} else {			if (flags & DP_F_SPACE)				signvalue = ' ';		}	}#if 0	if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */#endif#if 0	 if (max == 0) ufvalue += 0.5; /* if max = 0 we must round */#endif	/* 	 * Sorry, we only support 16 digits past the decimal because of our 	 * conversion method	 */	if (max > 16)		max = 16;	/* We "cheat" by converting the fractional part to integer by	 * multiplying by a factor of 10	 */	temp = ufvalue;	my_modf(temp, &intpart);	fracpart = ROUND((POW10(max)) * (ufvalue - intpart));		if (fracpart >= POW10(max)) {		intpart++;		fracpart -= POW10(max);	}	/* Convert integer part */	do {		temp = intpart;		my_modf(intpart*0.1, &intpart);		temp = temp*0.1;		index = (int) ((temp -intpart +0.05)* 10.0);		/* index = (int) (((double)(temp*0.1) -intpart +0.05) *10.0); */		/* printf ("%llf, %f, %x\n", temp, intpart, index); */		iconvert[iplace++] =			(caps? "0123456789ABCDEF":"0123456789abcdef")[index];	} while (intpart && (iplace < 311));	if (iplace == 311) iplace--;	iconvert[iplace] = 0;	/* Convert fractional part */	if (fracpart)	{		do {			temp = fracpart;			my_modf(fracpart*0.1, &fracpart);			temp = temp*0.1;			index = (int) ((temp -fracpart +0.05)* 10.0);			/* index = (int) ((((temp/10) -fracpart) +0.05) *10); */			/* printf ("%lf, %lf, %ld\n", temp, fracpart, index); */			fconvert[fplace++] =			(caps? "0123456789ABCDEF":"0123456789abcdef")[index];		} while(fracpart && (fplace < 311));		if (fplace == 311) fplace--;	}	fconvert[fplace] = 0;  	/* -1 for decimal point, another -1 if we are printing a sign */	padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); 	zpadlen = max - fplace;	if (zpadlen < 0) zpadlen = 0;	if (padlen < 0) 		padlen = 0;	if (flags & DP_F_MINUS) 		padlen = -padlen; /* Left Justifty */		if ((flags & DP_F_ZERO) && (padlen > 0)) {		if (signvalue) {			dopr_outch (buffer, currlen, maxlen, signvalue);			--padlen;			signvalue = 0;		}		while (padlen > 0) {			dopr_outch (buffer, currlen, maxlen, '0');			--padlen;		}	}	while (padlen > 0) {		dopr_outch (buffer, currlen, maxlen, ' ');		--padlen;	}	if (signvalue) 		dopr_outch (buffer, currlen, maxlen, signvalue);		while (iplace > 0) 		dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]);#ifdef DEBUG_SNPRINTF	printf("fmtfp: fplace=%d zpadlen=%d\n", fplace, zpadlen);#endif	/*	 * Decimal point.  This should probably use locale to find the correct	 * char to print out.	 */	if (max > 0) {		dopr_outch (buffer, currlen, maxlen, '.');				while (fplace > 0) 			dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]);	}		while (zpadlen > 0) {		dopr_outch (buffer, currlen, maxlen, '0');		--zpadlen;	}	while (padlen < 0) {		dopr_outch (buffer, currlen, maxlen, ' ');		++padlen;	}}static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c){	if (*currlen < maxlen) {		buffer[(*currlen)] = c;	}	(*currlen)++;}/* yes this really must be a ||. Don't muck with this (tridge) */#if !defined(HAVE_VSNPRINTF) || !defined(HAVE_C99_VSNPRINTF) int vsnprintf (char *str, size_t count, const char *fmt, va_list args){	return dopr(str, count, fmt, args);}#endif/* yes this really must be a ||. Don't muck wiith this (tridge) * * The logic for these two is that we need our own definition if the * OS *either* has no definition of *sprintf, or if it does have one * that doesn't work properly according to the autoconf test.  Perhaps * these should really be smb_snprintf to avoid conflicts with buggy * linkers? -- mbp */#if !defined(HAVE_SNPRINTF) || !defined(HAVE_C99_SNPRINTF) int snprintf(char *str,size_t count,const char *fmt,...){	size_t ret;	va_list ap;    	va_start(ap, fmt);	ret = vsnprintf(str, count, fmt, ap);	va_end(ap);	return ret;}#endif#endif #ifndef HAVE_VASPRINTF int vasprintf(char **ptr, const char *format, va_list ap){	int ret;		ret = vsnprintf(0, 0, format, ap);	if (ret <= 0) return ret;	(*ptr) = (char *)malloc(ret+1);	if (!*ptr) return -1;	ret = vsnprintf(*ptr, ret+1, format, ap);	return ret;}#endif#ifndef HAVE_ASPRINTF int asprintf(char **ptr, const char *format, ...){	va_list ap;	int ret;		*ptr = 0;	va_start(ap, format);	ret = vasprintf(ptr, format, ap);	va_end(ap);	return ret;}#endif#ifndef HAVE_VSYSLOG#ifdef HAVE_SYSLOG void vsyslog (int facility_priority, char *format, va_list arglist){	char *msg = 0;	vasprintf(&msg, format, arglist);        if (!msg)                return;        syslog(facility_priority, "%s", msg);        free(msg);}#endif /* HAVE_SYSLOG */#endif /* HAVE_VSYSLOG */#ifdef TEST_SNPRINTF int sprintf(char *str,const char *fmt,...); int main (void){	char buf1[1024];	char buf2[1024];	char *fp_fmt[] = {		"%1.1f",		"%-1.5f",		"%1.5f",		"%123.9f",		"%10.5f",		"% 10.5f",		"%+22.9f",		"%+4.9f",		"%01.3f",		"%4f",		"%3.1f",		"%3.2f",		"%.0f",		"%f",		"-16.16f",		0	};	double fp_nums[] = { 6442452944.1234, -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996, 			     0.9996, 1.996, 4.136,  0};	char *int_fmt[] = {		"%-1.5d",		"%1.5d",		"%123.9d",		"%5.5d",		"%10.5d",		"% 10.5d",		"%+22.33d",		"%01.3d",		"%4d",		"%d",		0	};	long int_nums[] = { -1, 134, 91340, 341, 0203, 0};	char *str_fmt[] = {		"10.5s",		"5.10s",		"10.1s",		"0.10s",		"10.0s",		"1.10s",		"%s",		"%.1s",		"%.10s",		"%10s",		0	};	char *str_vals[] = {"hello", "a", "", "a longer string", 0};	int x, y;	int fail = 0;	int num = 0;	printf ("Testing snprintf format codes against system sprintf...\n");	for (x = 0; fp_fmt[x] ; x++) {		for (y = 0; fp_nums[y] != 0 ; y++) {			int l1 = snprintf(0, 0, fp_fmt[x], fp_nums[y]);			int l2 = snprintf(buf1, sizeof(buf1), fp_fmt[x], fp_nums[y]);			sprintf (buf2, fp_fmt[x], fp_nums[y]);			if (strcmp (buf1, buf2)) {				printf("snprintf doesn't match Format: %s\n\tsnprintf = [%s]\n\t sprintf = [%s]\n", 				       fp_fmt[x], buf1, buf2);				fail++;			}			if (l1 != l2) {				printf("snprintf l1 != l2 (%d %d) %s\n", l1, l2, fp_fmt[x]);				fail++;			}			num++;		}	}	for (x = 0; int_fmt[x] ; x++) {		for (y = 0; int_nums[y] != 0 ; y++) {			int l1 = snprintf(0, 0, int_fmt[x], int_nums[y]);			int l2 = snprintf(buf1, sizeof(buf1), int_fmt[x], int_nums[y]);			sprintf (buf2, int_fmt[x], int_nums[y]);			if (strcmp (buf1, buf2)) {				printf("snprintf doesn't match Format: %s\n\tsnprintf = [%s]\n\t sprintf = [%s]\n", 				       int_fmt[x], buf1, buf2);				fail++;			}			if (l1 != l2) {				printf("snprintf l1 != l2 (%d %d) %s\n", l1, l2, int_fmt[x]);				fail++;			}			num++;		}	}	for (x = 0; str_fmt[x] ; x++) {		for (y = 0; str_vals[y] != 0 ; y++) {			int l1 = snprintf(0, 0, str_fmt[x], str_vals[y]);			int l2 = snprintf(buf1, sizeof(buf1), str_fmt[x], str_vals[y]);			sprintf (buf2, str_fmt[x], str_vals[y]);			if (strcmp (buf1, buf2)) {				printf("snprintf doesn't match Format: %s\n\tsnprintf = [%s]\n\t sprintf = [%s]\n", 				       str_fmt[x], buf1, buf2);				fail++;			}			if (l1 != l2) {				printf("snprintf l1 != l2 (%d %d) %s\n", l1, l2, str_fmt[x]);				fail++;			}			num++;		}	}	printf ("%d tests failed out of %d.\n", fail, num);	printf("seeing how many digits we support\n");	{		double v0 = 0.12345678901234567890123456789012345678901;		for (x=0; x<100; x++) {			snprintf(buf1, sizeof(buf1), "%1.1f", v0*pow(10, x));			sprintf(buf2,                "%1.1f", v0*pow(10, x));			if (strcmp(buf1, buf2)) {				printf("we seem to support %d digits\n", x-1);				break;			}		}	}	return 0;}#endif /* SNPRINTF_TEST */

⌨️ 快捷键说明

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