#include "tinyprintf.h" #include #include int tinyprintf(const char *format, ...) { if (format == NULL || *format == '\0') { return 0; } va_list ap; va_start(ap, format); int res = 0; size_t i = 0; while (format[i]) { if (format[i] != '%') { putchar(format[i]); res++; } else { dispatch(format[i + 1], ap, &res); format++; } format++; } va_end(ap); return res; } void dispatch(char c, va_list ap, int *res) { switch (c) { case '%': putchar('%'); (*res)++; break; case 'd': handle_d(va_arg(ap, int), res); break; case 'u': handle_u(va_arg(ap, unsigned int), res); break; case 'x': handle_x(va_arg(ap, unsigned int), res); break; case 'o': handle_o(va_arg(ap, unsigned int), res); break; case 'c': putchar(va_arg(ap, int)); (*res)++; break; case 's': handle_s(va_arg(ap, char *), res); break; default: putchar('%'); putchar(c); *res += 2; break; } } void handle_d(int val, int *res) { if (val < 0) { putchar('-'); (*res)++; val = -val; } if (val == 0) { putchar('0'); (*res)++; } int t = val; int n = 0; while (t > 0) { t /= 10; n++; } char *s = malloc(n * sizeof(char)); int m = n; if (s == NULL) { return; } n--; for (; n >= 0; n--) { s[n] = val % 10 + '0'; val /= 10; } // actual printing for (int i = 0; i < m; i++) { putchar(s[i]); (*res)++; } free(s); } void handle_s(char *s, int *res) { if (s == NULL) { char *text = "(null)"; for (; *text; text++) { putchar(*text); (*res)++; } return; } for (; *s; s++) { putchar(*s); (*res)++; } } void handle_u(unsigned int val, int *res) { if (val == 0) { putchar('0'); (*res)++; } unsigned int t = val; int n = 0; while (t > 0) { t /= 10; n++; } char *s = malloc(n * sizeof(char)); int m = n; if (s == NULL) { return; } n--; for (; n >= 0; n--) { s[n] = val % 10 + '0'; val /= 10; } // actual printing for (int i = 0; i < m; i++) { putchar(s[i]); (*res)++; } free(s); } void handle_x(unsigned int val, int *res) { if (val == 0) { putchar('0'); (*res)++; } unsigned int t = val; int n = 0; while (t > 0) { t /= 16; n++; } char *s = malloc(n * sizeof(char)); int m = n; if (s == NULL) { return; } n--; for (; n >= 0; n--) { s[n] = val % 16 + '0'; if (s[n] > '9') { s[n] = (s[n] - '0') % 10 + 'a'; } val /= 16; } // actual printing for (int i = 0; i < m; i++) { putchar(s[i]); (*res)++; } free(s); } void handle_o(unsigned int val, int *res) { if (val == 0) { putchar('0'); (*res)++; } unsigned int t = val; int n = 0; while (t > 0) { t /= 8; n++; } char *s = malloc(n * sizeof(char)); int m = n; if (s == NULL) { return; } n--; for (; n >= 0; n--) { s[n] = val % 8 + '0'; val /= 8; } // actual printing for (int i = 0; i < m; i++) { putchar(s[i]); (*res)++; } free(s); }