diff --git a/chapter_7.input_output/7_4.minscanf/Makefile b/chapter_7.input_output/7_4.minscanf/Makefile new file mode 100644 index 0000000..563c246 --- /dev/null +++ b/chapter_7.input_output/7_4.minscanf/Makefile @@ -0,0 +1,3 @@ +BINARY=minscanf + +include ../../Exercise.mk diff --git a/chapter_7.input_output/7_4.minscanf/main.c b/chapter_7.input_output/7_4.minscanf/main.c new file mode 100644 index 0000000..e98ef0e --- /dev/null +++ b/chapter_7.input_output/7_4.minscanf/main.c @@ -0,0 +1,29 @@ +# include +# include "minscanf.h" + +int main () +{ + int r; + char type; + + if ((r = minscanf("type: %c", &type)) == EOF || r != 1) { + printf("Error reading type. Format:\ntype t v0 v1 ... vn\nt - d: decimal int, f: float\n"); + return 0; + } + if (type == 'f') { + float v; + double sum = 0; + while ((r = minscanf("%f", &v)) != EOF && r == 1) + printf("\t%.2f\n", sum += v); + } + else if (type == 'd') { + int v; + long int sum = 0; + while ((r = minscanf("%d", &v)) != EOF && r == 1) + printf("\t%ld\n", sum += v); + } + else + printf("ERROR! Unrecognized type %c.\n", type); + + return 0; +} diff --git a/chapter_7.input_output/7_4.minscanf/minscanf.c b/chapter_7.input_output/7_4.minscanf/minscanf.c new file mode 100644 index 0000000..45a085a --- /dev/null +++ b/chapter_7.input_output/7_4.minscanf/minscanf.c @@ -0,0 +1,56 @@ +# include +# include + +/* minscanf: minimal scanf with variable argument list */ +int minscanf (char *fmt, ...) +{ + va_list ap; /* points to each annamed arg in turn */ + char *p; + int c, sr, r = 0; + + va_start(ap, fmt); /* make ap point to 1st unnamed arg */ + for (p = fmt; *p; p++) { + if (*p != '%') { + if ((c = getchar()) == EOF) { + va_end(ap); + return EOF; + } + else if (c != *p) { + va_end(ap); + return r; + } + } + else { + switch (*++p) { + case 'o': sr = scanf("%o", va_arg(ap, int*)); break; + case 'd': sr = scanf("%d", va_arg(ap, int*)); break; + case 'u': sr = scanf("%u", va_arg(ap, unsigned int*)); break; + case 'e': + case 'f': + case 'g': sr = scanf("%f", va_arg(ap, float*)); break; + case 'c': sr = scanf("%c", va_arg(ap, char*)); break; + case '%': + if (c == EOF) { + va_end(ap); + return EOF; + } + else if (c != '%') { + va_end(ap); + return r; + } + break; + default: + printf("ERROR! Unsupported conversion %%%c.\n", *p); + va_end(ap); + return EOF; + } + if (sr == EOF) { + va_end(ap); + return EOF; + } + r++; + } + } + va_end(ap); /* clean up when done */ + return r; +} diff --git a/chapter_7.input_output/7_4.minscanf/minscanf.h b/chapter_7.input_output/7_4.minscanf/minscanf.h new file mode 100644 index 0000000..23c46fb --- /dev/null +++ b/chapter_7.input_output/7_4.minscanf/minscanf.h @@ -0,0 +1,7 @@ +# ifndef MINSCANF_H +# define MINSCANF_H + +/* minscanf: minimal scanf with variable argument list */ +int minscanf (char *fmt, ...); + +# endif diff --git a/chapter_7.input_output/7_4.minscanf/tests/00_err_no_type.tin b/chapter_7.input_output/7_4.minscanf/tests/00_err_no_type.tin new file mode 100644 index 0000000..b85905e --- /dev/null +++ b/chapter_7.input_output/7_4.minscanf/tests/00_err_no_type.tin @@ -0,0 +1 @@ +1 2 3 diff --git a/chapter_7.input_output/7_4.minscanf/tests/00_err_no_type.tout b/chapter_7.input_output/7_4.minscanf/tests/00_err_no_type.tout new file mode 100644 index 0000000..270e6a8 --- /dev/null +++ b/chapter_7.input_output/7_4.minscanf/tests/00_err_no_type.tout @@ -0,0 +1,3 @@ +Error reading type. Format: +type t v0 v1 ... vn +t - d: decimal int, f: float diff --git a/chapter_7.input_output/7_4.minscanf/tests/01_err_wrong_type.tin b/chapter_7.input_output/7_4.minscanf/tests/01_err_wrong_type.tin new file mode 100644 index 0000000..fc38a1e --- /dev/null +++ b/chapter_7.input_output/7_4.minscanf/tests/01_err_wrong_type.tin @@ -0,0 +1 @@ +type X 1 2 3 diff --git a/chapter_7.input_output/7_4.minscanf/tests/01_err_wrong_type.tout b/chapter_7.input_output/7_4.minscanf/tests/01_err_wrong_type.tout new file mode 100644 index 0000000..270e6a8 --- /dev/null +++ b/chapter_7.input_output/7_4.minscanf/tests/01_err_wrong_type.tout @@ -0,0 +1,3 @@ +Error reading type. Format: +type t v0 v1 ... vn +t - d: decimal int, f: float diff --git a/chapter_7.input_output/7_4.minscanf/tests/1_d_2.tin b/chapter_7.input_output/7_4.minscanf/tests/1_d_2.tin new file mode 100644 index 0000000..f4e0284 --- /dev/null +++ b/chapter_7.input_output/7_4.minscanf/tests/1_d_2.tin @@ -0,0 +1 @@ +type: d -100 101 diff --git a/chapter_7.input_output/7_4.minscanf/tests/1_d_2.tout b/chapter_7.input_output/7_4.minscanf/tests/1_d_2.tout new file mode 100644 index 0000000..adb6017 --- /dev/null +++ b/chapter_7.input_output/7_4.minscanf/tests/1_d_2.tout @@ -0,0 +1,2 @@ + -100 + 1 diff --git a/chapter_7.input_output/7_4.minscanf/tests/2_d_6.tin b/chapter_7.input_output/7_4.minscanf/tests/2_d_6.tin new file mode 100644 index 0000000..17ea55e --- /dev/null +++ b/chapter_7.input_output/7_4.minscanf/tests/2_d_6.tin @@ -0,0 +1 @@ +type: d -100 -10 1 12 123 1234567890 diff --git a/chapter_7.input_output/7_4.minscanf/tests/2_d_6.tout b/chapter_7.input_output/7_4.minscanf/tests/2_d_6.tout new file mode 100644 index 0000000..f7e0ac9 --- /dev/null +++ b/chapter_7.input_output/7_4.minscanf/tests/2_d_6.tout @@ -0,0 +1,6 @@ + -100 + -110 + -109 + -97 + 26 + 1234567916 diff --git a/chapter_7.input_output/7_4.minscanf/tests/3_f_2.tin b/chapter_7.input_output/7_4.minscanf/tests/3_f_2.tin new file mode 100644 index 0000000..711c5c6 --- /dev/null +++ b/chapter_7.input_output/7_4.minscanf/tests/3_f_2.tin @@ -0,0 +1 @@ +type: f -100.5 101.05 diff --git a/chapter_7.input_output/7_4.minscanf/tests/3_f_2.tout b/chapter_7.input_output/7_4.minscanf/tests/3_f_2.tout new file mode 100644 index 0000000..859bf8a --- /dev/null +++ b/chapter_7.input_output/7_4.minscanf/tests/3_f_2.tout @@ -0,0 +1,2 @@ + -100.50 + 0.55 diff --git a/chapter_7.input_output/7_4.minscanf/tests/4_f_6.tin b/chapter_7.input_output/7_4.minscanf/tests/4_f_6.tin new file mode 100644 index 0000000..8a69ac3 --- /dev/null +++ b/chapter_7.input_output/7_4.minscanf/tests/4_f_6.tin @@ -0,0 +1 @@ +type: f -.100 -.10 .1 .12 1.23 12.34567890 diff --git a/chapter_7.input_output/7_4.minscanf/tests/4_f_6.tout b/chapter_7.input_output/7_4.minscanf/tests/4_f_6.tout new file mode 100644 index 0000000..df247cc --- /dev/null +++ b/chapter_7.input_output/7_4.minscanf/tests/4_f_6.tout @@ -0,0 +1,6 @@ + -0.10 + -0.20 + -0.10 + 0.02 + 1.25 + 13.60 diff --git a/chapter_7.input_output/7_4.minscanf/xx b/chapter_7.input_output/7_4.minscanf/xx new file mode 100644 index 0000000..9e8d2ec --- /dev/null +++ b/chapter_7.input_output/7_4.minscanf/xx @@ -0,0 +1,2 @@ + 1.00 + 3.00