📄 mprintf.c
字号:
/******************************************************************************* author : Frank N黚el filename : ghmm/ghmm/mprintf.c created : TIME: 11:27:16 DATE: Wed 14. May 1997 $Id: mprintf.c,v 1.3 2001/04/22 20:21:49 achim Exp $Copyright (C) 1998-2001, ZAIK/ZPR, Universit鋞 zu K鰈nThis program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe 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 ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*******************************************************************************/#include <stdio.h>#include <string.h>#include <stdlib.h>#include <time.h>#ifdef WIN32 #include <windows.h> #include <io.h>#endif#include "mprintf.h"#define MPRINTF_FLAG_LEFT 1#define MPRINTF_FLAG_ZERO 2#define MPRINTF_FLAG_PLUS 4#define MPRINTF_FLAG_SPACE 8#define MPRINTF_FLAG_FLAT 16 #define MPRINTF_TMP_LEN 1024#define MPRINTF_FRM_LEN 64/*----------------------------------------------------------------------------*/static int mprintf_int( char*dst, int dlen, int x ) { int i; if( !x ) { *dst++ = '0'; *dst++ = 0; return(1); } for( i = dlen; x && i > 0; ) { dst[--i] = x % 10 + '0'; x /= 10; } memcpy( dst, dst + i, dlen - i ); if( i > 0 ) i = dlen - i; else i = dlen - 1; dst[i] = 0; return(i);} /* mprintf_int *//*----------------------------------------------------------------------------*/static void mprintf_conv_float( char* dst, int flags, int minwidth, int precision, char sizemodif, char convchar, long double x ) { char tmp[MPRINTF_FRM_LEN]; int i = 0;; tmp[i++] = '%'; if( flags & MPRINTF_FLAG_LEFT ) tmp[i++] = '-'; if( flags & MPRINTF_FLAG_PLUS ) tmp[i++] = '+'; if( flags & MPRINTF_FLAG_SPACE ) tmp[i++] = ' '; if( flags & MPRINTF_FLAG_FLAT ) tmp[i++] = '#'; if( flags & MPRINTF_FLAG_ZERO ) tmp[i++] = '0'; if( minwidth > 0 ) i += mprintf_int( tmp + i, MPRINTF_FRM_LEN - i, minwidth ); if( precision >= 0 ) { tmp[i++] = '.'; i += mprintf_int( tmp + i, MPRINTF_FRM_LEN - i, precision ); } if( sizemodif ) tmp[i++] = sizemodif; tmp[i++] = convchar; tmp[i] = 0; if( sizemodif == 'L' ) sprintf( dst, tmp, x ); else sprintf( dst, tmp, (double)x ); return;} /* mprintf_conv_float *//*----------------------------------------------------------------------------*/static void mprintf_conv_str( char* dst, int flags, int minwidth, int precision, char* src ) { char *p; int zeros; dst[0] = 0; if( !src ) return; p = memchr( src, 0, precision ); if( p ) precision = p - src; if( !(flags & MPRINTF_FLAG_ZERO) || minwidth < precision ) zeros = 0; else zeros = minwidth - precision; minwidth -= precision + zeros; if( minwidth < 0 ) minwidth = 0; if( flags & MPRINTF_FLAG_LEFT ) { if( zeros ) memset( dst, '0', zeros ); memcpy( dst + zeros, src, precision ); if( minwidth ) memset( dst + zeros + precision, ' ', minwidth ); } else { if( minwidth ) memset( dst, ' ', minwidth ); if( zeros ) memset( dst + minwidth, '0', zeros ); memcpy( dst + minwidth + zeros, src, precision ); } dst[zeros + precision + minwidth] = 0; return;} /* mprintf_conv_str *//*----------------------------------------------------------------------------*/static void mprintf_conv_int( char* dst, int flags, int minwidth, int precision, char convchar, unsigned int x ){ int i = x; char neg = 0; int k; int fillchars; char aux; if( precision < 1 ) precision = 1; if( i < 0 && (convchar == 'i' || convchar == 'd') ) { x = -x; neg = 1; } if( strchr( "uoxXbc", convchar ) ) { flags &= ~MPRINTF_FLAG_PLUS; flags &= ~MPRINTF_FLAG_SPACE; } if( strchr( "duci", convchar ) ) { flags &= ~MPRINTF_FLAG_FLAT; } k = MPRINTF_TMP_LEN; switch( convchar ) { case 'u': case 'd': case 'i': for( ; x && k > 0; ) { dst[--k] = x % 10 + '0'; x /= 10; } break; case 'o': for( ; x && k > 0; ) { dst[--k] = (x & 7) + '0'; x >>= 3; } break; case 'X': case 'x': aux = convchar - 'X' + 'A' - '0' - 10; for( ; x && k > 0; ) { dst[--k] = (x & 0xF) + '0'; x >>= 4; if( dst[k] > '9' ) dst[k] += aux; } break; case 'b': for( ; x && k > 0; ) { dst[--k] = (x & 1) + '0'; x >>= 1; } break; case 'c': if( x ) dst[--k] = x; else dst[--k] = -1; break; } while( MPRINTF_TMP_LEN - k < precision ) dst[--k] = '0'; if( minwidth > 0 && flags & MPRINTF_FLAG_ZERO) { fillchars = minwidth - (MPRINTF_TMP_LEN - k); if( neg ) fillchars--; else if( flags & (MPRINTF_FLAG_SPACE | MPRINTF_FLAG_PLUS) ) fillchars--; if( flags & MPRINTF_FLAG_FLAT ) { if( convchar == 'o' ) fillchars--; else if( strchr( "Xxb", convchar ) ) fillchars -= 2; } while( fillchars-- > 0 ) dst[--k] = '0'; } if( neg ) dst[--k] = '-'; else if( flags & MPRINTF_FLAG_SPACE ) dst[--k] = ' '; else if( flags & MPRINTF_FLAG_PLUS ) dst[--k] = '+'; if( flags & MPRINTF_FLAG_FLAT ) { switch( convchar ) { case 'o' : dst[--k] = '0'; break; case 'X' : dst[--k] = 'X'; dst[--k] = '0'; break; case 'x' : dst[--k] = 'x'; dst[--k] = '0'; break; case 'b' : dst[--k] = '_'; dst[--k] = '0'; break; } } if( flags & MPRINTF_FLAG_LEFT ) { memcpy( dst, dst + k, MPRINTF_TMP_LEN - k ); k = MPRINTF_TMP_LEN - k; while( k < minwidth ) dst[k++] = ' '; dst[k] = 0; } else { if( minwidth > 0 ) fillchars = minwidth - (MPRINTF_TMP_LEN - k); else fillchars = 0; if( fillchars < 0) fillchars = 0; for( i = fillchars; i-- > 0; ) dst[i] = ' '; memcpy( dst + fillchars, dst + k, MPRINTF_TMP_LEN - k ); dst[fillchars + MPRINTF_TMP_LEN - k] = 0; } return;} /* mprintf_conv_int*//*----------------------------------------------------------------------------*/static int mprintf_scan_int( char** src, va_list* ap ) { char* p = *src; int res = 0; if( *p == '*' ) { res = va_arg( *ap, int ); p++; } else while( *p <= '9' && *p >= '0' ) { res = res * 10 + (*p - '0' ); p ++; } if( res < 0 ) res = -res; if( p == *src ) res = -1; *src = p; return(res);} /* mprintf_scan_int *//*----------------------------------------------------------------------------*/static char* mprintf_get_next( char** format, int* flen, int* dlen, va_list* ap ){ static char tmp[MPRINTF_TMP_LEN]; char* res = NULL; int minwidth = -1; int maxwidth = MPRINTF_TMP_LEN - 1; int precision = -1; char sizemodif = 0; char convchar = 0; int flags = 0; char* src; int leave; long double aux_float; clock_t clock_diff; tmp[0] = 0; /* skip '%' : */ src = *format + 1; *dlen = 0; while( 1 ) { /* scan flags : */ leave = 0; while( *src ) { switch( *src ) { case '-' : flags |= MPRINTF_FLAG_LEFT; break; case '0' : flags |= MPRINTF_FLAG_ZERO; break; case '+' : flags |= MPRINTF_FLAG_PLUS; break; case ' ' : flags |= MPRINTF_FLAG_SPACE; break; case '#' : flags |= MPRINTF_FLAG_FLAT; break; default : leave = 1; break; } if( leave ) break; src++; } if( !*src ) break; /* scan minwidth : */ minwidth = mprintf_scan_int( &src, ap ); if( !*src ) break; if( minwidth >= MPRINTF_TMP_LEN ) minwidth = MPRINTF_TMP_LEN - 1; /* scan precision : */ if( *src == '.' ) { src++; precision = mprintf_scan_int( &src, ap ); if( !*src ) break; } /* scan maxwidth : */ if( *src == ':' ) { src++; maxwidth = mprintf_scan_int( &src, ap ); if( !*src ) break; if( !maxwidth ) { res = tmp; break; } } /* scan size modifier : */ if( strchr( "hlL", *src ) ) sizemodif = *src++; if( !*src ) break; /* scan conversion letter */ if ( !strchr( "diuoxXfeEgGcspntTb", *src ) ) break; convchar = *src++; if( maxwidth < 0 || maxwidth >= MPRINTF_TMP_LEN) maxwidth = MPRINTF_TMP_LEN-1; if( minwidth > maxwidth ) minwidth = maxwidth; leave = 0; switch( convchar ) { case 'c' : case 'd' : case 'i' : case 'u' : case 'o' : case 'x' : case 'X' : case 'b' : mprintf_conv_int( tmp, flags, minwidth, precision, convchar, va_arg( *ap, int ) ); break;#if 0 /* makes only trouble*/ case 'p' : mprintf_conv_int( tmp, flags, minwidth, precision, 'X', (int)(va_arg( *ap, char* )) ); break;#endif /* 0 */ case 's' : if( precision < 0 || precision > maxwidth ) precision = maxwidth; mprintf_conv_str( tmp, flags, minwidth, precision, va_arg( *ap, char* ) ); maxwidth = MPRINTF_TMP_LEN-1; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -