繼續sprintf函式,這次親自動手寫了一個myprintf,是不是更有意思了,當然別指望我的程式碼沒有bug。
#include <stdio.h>
typedef char *va_list;
#define __va_rounded_size(TYPE) \ (((sizeof(TYPE)+sizeof(int)-1)/sizeof(int))*sizeof(int))
#define va_start(AP, LASTARG) \ (AP=((char *)&(LASTARG)+__va_rounded_size(LASTARG)))
#define va_end(AP) ((va_list)0)
#define va_arg(AP, TYPE) \ (AP+=__va_rounded_size(TYPE), \ *((TYPE *)(AP-__va_rounded_size(TYPE))))
int myprintf(char *buf, char *fmt, ...); void itoa(int num, char *buf, unsigned int base); unsigned int div(unsigned int *n, unsigned int b);
int main(void) { char buf[0x100]; myprintf(buf, " s d x c \ s", "Hello World!", 0xfffe, 65535, 'c', "sssss"); printf("%s", buf); }
int myprintf(char *buf, char *fmt, ...) { va_list ap; va_start(ap, fmt); char buf1[64], *temp1; int d; char *s, c; while (*fmt) { switch (*fmt++) { case 's': s = (char *)va_arg(ap, char *); // printf("%s\n", s); while(*s) *buf++ = *s++; break; case 'c': c = (char)va_arg(ap, char); // printf("%c\n", c); *buf++ = c; break; case 'd': d = (int)va_arg(ap, int); // printf("%d\n", d); itoa(d, buf1, 10); temp1 = buf1; while (*temp1) { *buf++ = *temp1++; } // printf("*************%s\n", buf1); break; case 'x': d = (int)va_arg(ap, int); // printf("%d\n", d); *buf++ = '0'; *buf++ = 'x'; itoa(d, buf1, 16); temp1 = buf1; while (*temp1) { *buf++ = *temp1++; } // printf("*************%s\n", buf1); break; case ' ': // printf("|Space|\n"); *buf++ = ' '; break; } } va_end(ap); *buf = '\0'; }
unsigned int div(unsigned int *n, unsigned int b) { int res; res = *n % b; *n = *n / b; return res; }
void itoa(int num, char *buf, unsigned int base) { char digits[16] = "0123456789abcdef"; char temp[64]; int i = 0; while (num) *(temp + i++) = digits[div(&num, base)]; while (i-- > 0) *buf++ = *(temp + i); *(buf) = '\0'; }