📄 snprintf.c
字号:
/* * Copyright (c) 1996 The Regents of the University of California. * All rights reserved. * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose, without fee, and without written agreement * is hereby granted, provided that the above copyright notice and the * following two paragraphs appear in all copies of this software. * * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING * OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE * UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. * * $Id: snprintf.c,v 1.3 1996/08/31 02:53:37 aswan Exp $ * * This is stolen directly from Patrick Powell (papowell@sdsu.edu) * It was originally posted to the bugtraq mailing list... */static void dopr();static char *end, *etext, *edata;#include <sys/types.h>/* varargs declarations: */#if defined(HAVE_STDARG_H)# include <stdarg.h># define HAVE_STDARGS /* let's hope that works everywhere (mj) */# define VA_LOCAL_DECL va_list ap;# define VA_START(f) va_start(ap, f)# define VA_SHIFT(v,t) ; /* no-op for ANSI */# define VA_END va_end(ap)#else# if defined(HAVE_VARARGS_H)# include <varargs.h># undef HAVE_STDARGS# define VA_LOCAL_DECL va_list ap;# define VA_START(f) va_start(ap) /* f is ignored! */# define VA_SHIFT(v,t) v = va_arg(ap,t)# define VA_END va_end(ap)# elseXX ** NO VARARGS ** XX# endif#endifint vsnprintf(str, count, fmt, args) char *str; size_t count; const char *fmt; va_list args;{ str[0] = 0; end = str+count-1; dopr( str, fmt, args ); if( count>0 ){ end[0] = 0; } return(strlen(str));}/* VARARGS3 */#ifdef HAVE_STDARGSint snprintf (char *str,size_t count,const char *fmt,...)#elseint snprintf (va_alist) va_dcl#endif{#ifndef HAVE_STDARGS char *str; size_t count; char *fmt;#endif VA_LOCAL_DECL VA_START (fmt); VA_SHIFT (str, char *); VA_SHIFT (count, size_t ); VA_SHIFT (fmt, char *); (void) vsnprintf ( str, count, fmt, ap); VA_END; return( strlen( str ) );}/* * dopr(): poor man's version of doprintf */static void fmtstr( char *value, int ljust, int len, int zpad );static void fmtnum( long value, int base, int dosign, int ljust, int len, int zpad );static void dostr( char * );static char *output;static void dopr_outch( int c );static void dopr( buffer, format, args ) char *buffer; char *format; va_list args;{ int ch; long value; int longflag = 0; char *strvalue; int ljust; int len; int prec; int zpad; output = buffer; while( (ch = *format++) ){ prec = 0; len = 0; switch( ch ){ case '%': ljust = len = zpad = 0; nextch: ch = *format++; switch( ch ){ case 0: dostr( "**end of format**" ); return; case '-': ljust = 1; goto nextch; case '0': /* set zero padding if len not set */ if(len==0) zpad = '0'; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': len = len*10 + ch - '0'; goto nextch; case 'l': longflag = 1; goto nextch; case 'u': case 'U': /*fmtnum(value,base,dosign,ljust,len,zpad) */ if( longflag ){ value = va_arg( args, long ); } else { value = va_arg( args, int ); } fmtnum( value, 10,0, ljust, len, zpad ); break; case 'o': case 'O': /*fmtnum(value,base,dosign,ljust,len,zpad) */ if( longflag ){ value = va_arg( args, long ); } else { value = va_arg( args, int ); } fmtnum( value, 8,0, ljust, len, zpad ); break; case 'd': case 'D': if( longflag ){ value = va_arg( args, long ); } else { value = va_arg( args, int ); } fmtnum( value, 10,1, ljust, len, zpad ); break; case 'x': if( longflag ){ value = va_arg( args, long ); } else { value = va_arg( args, int ); } fmtnum( value, 16,0, ljust, len, zpad ); break; case 'X': if( longflag ){ value = va_arg( args, long ); } else { value = va_arg( args, int ); } fmtnum( value,-16,0, ljust, len, zpad ); break; case 's': strvalue = va_arg( args, char *); fmtstr( strvalue,ljust,len,zpad ); break; case 'c': ch = va_arg( args, int ); dopr_outch( ch ); break; case '*': len = va_arg( args, int); goto nextch; case '.': ch = *format++; if (ch == '*') { prec = va_arg( args, int); } else { int n; while (isdigit(ch)) { n = n*10 + ch - '0'; ch = *format++; } prec = n < 0 ? -1 : n; } goto nextch; case '%': dopr_outch( ch ); continue; default: dostr( "???????" ); } longflag = 0; break; default: dopr_outch( ch ); break; } } *output = 0;}static voidfmtstr( value, ljust, len, zpad ) char *value; int ljust, len, zpad;{ int padlen, strlen; /* amount to pad */ if (value < (char *)0x1000) /* check for possibly memory fault conditions */ return; if( value == 0 ){ value = ""; } for( strlen = 0; value[strlen] ; strlen++ ); /* strlen */ padlen = len - strlen; if( padlen < 0 ) padlen = 0; if( ljust ) padlen = -padlen; while( padlen > 0 ) { dopr_outch( ' ' ); --padlen; } dostr( value ); while( padlen < 0 ) { dopr_outch( ' ' ); ++padlen; }}static voidfmtnum( value, base, dosign, ljust, len, zpad ) long value; int base, dosign, ljust, len, zpad;{ int signvalue = 0; unsigned long uvalue; char convert[20]; int place = 0; int padlen = 0; /* amount to pad */ int caps = 0; /* DEBUGP(("value 0x%x, base %d, dosign %d, ljust %d, len %d, zpad %d\n", value, base, dosign, ljust, len, zpad )); */ uvalue = value; if( dosign ){ if( value < 0 ) { signvalue = '-'; uvalue = -value; } } if( base < 0 ){ caps = 1; base = -base; } do{ convert[place++] = (caps? "0123456789ABCDEF":"0123456789abcdef") [uvalue % (unsigned)base ]; uvalue = (uvalue / (unsigned)base ); }while(uvalue); convert[place] = 0; padlen = len - place; if( padlen < 0 ) padlen = 0; if( ljust ) padlen = -padlen; /* DEBUGP(( "str '%s', place %d, sign %c, padlen %d\n", convert,place,signvalue,padlen)); */ if( zpad && padlen > 0 ){ if( signvalue ){ dopr_outch( signvalue ); --padlen; signvalue = 0; } while( padlen > 0 ){ dopr_outch( zpad ); --padlen; } } while( padlen > 0 ) { dopr_outch( ' ' ); --padlen; } if( signvalue ) dopr_outch( signvalue ); while( place > 0 ) dopr_outch( convert[--place] ); while( padlen < 0 ){ dopr_outch( ' ' ); ++padlen; }}static void dostr( str ) char *str;{ while(*str) dopr_outch(*str++);}static void dopr_outch( c ) int c;{ c = c & 0xff; if( iscntrl(c) && !isspace(c)) { c = '@' + (c & 0x1F); if( end == 0 || output < end ){ *output++ = '^'; } } if( end == 0 || output < end ){ *output++ = c; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -