printf () is the most commonly used function in the console program, which uses the input characters, numbers, and other information to spell the complete sentence and output to the standard output device (monitor, console, etc.).
The following is the printf () Definition:
int printf (const char *FMT, ...)
printf () Implementation section:
int test_printf (const char *fmt, ...)
{
//define the maximum length of 1024 bytes
Char printf_buf[1024] for receiving output information;
Record FMT The corresponding address
va_list args;
int printed;
Get the first% corresponding character address
Test_va_start (args, fmt);
Printed = test_vsprintf (Printf_buf, FMT, args);
Test_va_end (args);
Output to standard output device
puts (PRINTF_BUF);
return printed;
}
Call Partial implementation:
typedef char * VA_LIST; #ifdef __cplusplus//Gets the address of the parameter v #define _ADDRESSOF (v) (&reinterpret_cast<const Char &> (v)) #else #def Ine _addressof (v) (& (v)) #endif #define _INTSIZEOF (n) ((sizeof (n) + sizeof (int)-1) & ~ sizeof (int)- 1) #define _crt_va_start (ap,v) (AP = (va_list) _addressof (v) + _intsizeof (v)) #define _CRT_VA_ARG (Ap,t) (* (t *) ((AP + _intsizeof (t))-_intsizeof (t)) #define _CRT_VA_END (AP) (AP = (va_list) 0) #define Test_va_start _c Rt_va_start/* Windows Stdarg.h/#define TEST_VA_ARG _crt_va_arg #define Test_va_end _crt_va_end #define Zeropad
1/* Pad with zero */#define SIGN 2/* unsigned/signed LONG/#define PLUS 4/* Show plus * * #define SPACE 8/* space if plus/#define LEFT/* Left justified/#define SPECIAL/* 0x * * #define LARGE/* use ' ABCDEF ' instead of ' ABCDEF '/int _div (long* n,unsigned base) {int __res;
__res = ((unsigned long) *n)% (unsigned) base;
*n = ((unsigned long) *n)/(unsigned) base;
return __res;
#define DO_DIV (N,base) _div (&n,base)/* ({\ int __res; \ __res = ((unsigned long) n)% (unsigned) base; \ n = ((unsigned long) n)/(unsigned) base; \ __res;
} */static inline int isdigit (int ch) {return (ch >= ' 0 ') && (ch <= ' 9 ');
} static int Skip_atoi (const char **s) {int i = 0;
while (IsDigit (**s)) i = i * + * (*s) + +)-' 0 ';
return i; Static Char *test_number (char *str, long num, int base, int size, int precision, int type) {char C, sign,
TMP[66];
const char *digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int i;
if (type & LARGE) digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
if (type & left) type &= ~zeropad;
if (Base < 2 | | | Base >) return 0; c = (type & zeropad)? ' 0 ': '';
sign = 0;
if (type & SIGN) {if (num < 0) {SIGN = '-';
num =-num;
size--;
else if (type & PLUS) {sign = ' + ';
size--;
else if (type & space) {sign = ';
size--;
} if (type & SPECIAL) {if (base = =) Size = 2;
else if (base = = 8) size--;
} i = 0;
if (num = = 0) {tmp[i++] = ' 0 ';
else {while (num!= 0) {tmp[i++] = digits[do_div (num, base)];
} if (i > Precision) precision = i;
size = precision; if (!) (
Type & (Zeropad + left)) while (size--> 0) *str++ = ';
if (sign) *str++ = sign;
if (type & SPECIAL) {if (base = = 8) *str++ = ' 0 ';
else if (base = =) {*str++ = ' 0 '; *str++ = Digits[33]; } if (! (
Type & left), while (size--> 0) *str++ = c;
while (I < precision--) *str++ = ' 0 ';
while (i--> 0) *str++ = tmp[i];
while (size--> 0) *str++ = ';
return str;
int test_vsprintf (char *buf, const char *fmt, va_list args) {int len;
unsigned long num;
int I, base;
Char *str;
const char *s; int flags; * Flags to Test_number () */int field_width; /* Width of output field */int precision; * min. # of digits for integers; Max Test_number of chars for from String */int qualifier; /* ' h ', ' l ', or ' l ' for integer fields */for (str = BUF; *fmt ++fmt) {if (*fmt!= '% ') {*str+
+ = *FMT;
Continue
} * Process Flags/flags = 0; Repeat: ++fmt;
/* This also skips the "*"/switch (*FMT) {case '-': Flags |= left;
Goto repeat;
Case ' + ': Flags |= PLUS;
Goto repeat;
Case ": Flags |= space;
Goto repeat;
Case ' # ': Flags |= SPECIAL;
Goto repeat;
Case ' 0 ': Flags |= zeropad;
Goto repeat;
/* Get field width */field_width =-1;
if (IsDigit (*fmt)) Field_width = Skip_atoi (&FMT);
else if (*fmt = = ' * ') {++fmt;
* * It's next argument/field_width = Test_va_arg (args, int);
if (Field_width < 0) {field_width =-field_width;
Flags |= left;
}/* Get the precision * * precision =-1; if (*fmt = = '. ')
{++fmt;
if (IsDigit (*fmt)) precision = Skip_atoi (&FMT);
else if (*fmt = = ' * ') {++fmt; * * It's next argument/precision = Test_va_arg (args, int);
} if (Precision < 0) Precision = 0;
}/* Get the conversion qualifier * * qualifier =-1;
if (*fmt = = ' h ' | | | *fmt = = ' L ' | | | *fmt = = ' L ') {qualifier = *fmt;
++FMT;
}/* Default base */base = 10; Switch (*FMT) {case ' C ': if (!) (
Flags & left), while (--field_width > 0) *str++ = ';
*str++ = (unsigned char) test_va_arg (args, int);
while (--field_width > 0) *str++ = ';
Continue
Case ' s ': s = Test_va_arg (args, char *);
Len = Strnlen (s, precision); if (!) (
Flags & left), while (Len < field_width--) *str++ = ';
for (i = 0; i < len; ++i) *str++ = *s++;
while (Len < field_width--) *str++ = ';
Continue
Case ' P ': if (field_width = = 1) {field_width = 2 * sizeof (void *);
Flags |= Zeropad;
str = Test_number (str, (unsigned long) test_va_arg (args, void *), 16,
Field_width, precision, flags);
Continue
Case ' n ': if (qualifier = = ' L ') {Long *ip = Test_va_arg (args, long *);
*ip = (STR-BUF);
else {int *ip = Test_va_arg (args, int *);
*ip = (STR-BUF);
} continue;
Case '% ': *str++ = '% ';
Continue
/* Integer test_number formats-set up of the flags and "break" * * case ' o ': base = 8;
Break
Case ' X ': Flags |= LARGE; Case ' x ': base = 16;
Break
Case ' d ': Case ' I ': Flags |= SIGN;
Case ' u ': break;
Default: *str++ = '% ';
if (*fmt) *str++ = *fmt;
else--fmt;
Continue
} if (qualifier = = ' l ') num = Test_va_arg (args, unsigned long);
else if (qualifier = = ' h ') {num = (unsigned short) test_va_arg (args, int);
if (Flags & SIGN) num = (short) num;
else if (Flags & SIGN) num = Test_va_arg (args, int);
else num = Test_va_arg (args, unsigned int);
str = test_number (str, num, base, field_width, precision, flags);
} *str = ' I ';
return str-buf;
}