aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ch7/7-03_minprintf.c75
1 files changed, 75 insertions, 0 deletions
diff --git a/ch7/7-03_minprintf.c b/ch7/7-03_minprintf.c
new file mode 100644
index 0000000..92cbde1
--- /dev/null
+++ b/ch7/7-03_minprintf.c
@@ -0,0 +1,75 @@
+#include <stdio.h>
+#include <stdarg.h>
+
+/* The C Programming Language: 2nd Edition
+ *
+ * Exercise 7-3: Revise `minprintf` to handle more of the other facilities
+ * of `printf`.
+ *
+ * Notes: It doesn't specify *which* facilities, or how many, so we'll choose
+ * three:
+ *
+ * o - octal
+ * x - hexadecimal
+ * c - unsigned char
+ *
+ * Since we're passing to printf(), this was easy. Doing it ourselves would
+ * take some more work. But we'll skirt by with the minimum.
+ */
+
+void minprintf(char *fmt, ...) {
+ va_list ap;
+ char *p, *sval;
+ int ival;
+ double dval;
+ va_start(ap, fmt);
+ for (p = fmt; *p; p++) {
+ if (*p != '%') {
+ putchar(*p);
+ continue;
+ }
+ switch (*++p) {
+ case 'd':
+ ival = va_arg(ap, int);
+ printf("%d", ival);
+ break;
+ case 'f':
+ dval = va_arg(ap, double);
+ printf("%f", dval);
+ break;
+ case 's':
+ for (sval = va_arg(ap, char *); *sval; sval++) {
+ putchar(*sval);
+ }
+ break;
+ case 'c':
+ ival = va_arg(ap, int);
+ printf("%c", ival);
+ break;
+ case 'x':
+ ival = va_arg(ap, int);
+ printf("0x");
+ printf("%x", ival);
+ break;
+ case 'o':
+ ival = va_arg(ap, int);
+ printf("0o");
+ printf("%o", ival);
+ break;
+ default:
+ putchar(*p);
+ break;
+ }
+ }
+ va_end(ap);
+}
+
+int main(int argc, char *argv[]) {
+ /* Should output 0o144 */
+ minprintf("100 = %o\n", 100);
+ /* Should output 0x64 */
+ minprintf("100 = %x\n", 100);
+ /* Should output a semicolon */
+ minprintf("char(0x59) = %c\n", 59);
+ return 0;
+}