2 Proprietary Rand Corporation
, 1981.
3 Further distribution of
this software
4 subject to the terms of the Rand
9 /* inputf is roughly complementary to printf,
10 except input comes from getchar (may be
11 user supplied, must return 0 at eof). in addition
12 all args must be pointers (addresses). the first arg
13 is the format string. '%' is used as the escape char as in
14 printf. the general format is %w.dc where w and d are decimal
15 character counts, and c is one of (d, o, i, f, e, s, c, x).
16 the args are all assumed to be pointers to the appropriate
17 typed args -- note all floating point is assumed to be float
18 unless the %e format is used (extended float). if w is omitted
19 the field ends with the first field delimeter (typically, space, comma,
20 and newline -- these can be specified by following the specification
21 by a list of chars before the next '%'). d represents the default
22 number of decimal places for 'f' and 'e' if no explicit
23 decimal point. for 's' w is the width of the field, and d is
24 the maximum number of chars after stripping off delimeters
25 on either end. s and c are approximately identical, except
26 that s returns a pointer into a static buffer, and c returns char
27 by char into the program itself, which means a 'd' specification
28 for c is essential, and in fact 1 is assumed as a default (as opposed
29 to infinity for s). if a w field is specified, the input data
30 is assumed to be in a fixed format, with exactly w columns
31 devoted to the designated field. this means that data in this format
32 does not have to be separated by blanks, etc. chars in the format
33 string before the first '%' are output before any requests
34 to the subroutine for chars. e.g.:
35 inputf("-> %i%e%s\n",&integ, &dbl, &charptr);
36 would read an integer into integ, a double into dbl, and a string
37 terminated only by a <nl> into a static buffer, returning its start
38 addr in charptr, after prompting with "-> ". */
39 #define DFTSEP ",; \t\n\r" /* default field separators */
40 #define NEXTCHR getchar() /* character input routine */
41 #define SCBLEN 100 /* max. no. of chars in static char buff */
42 struct { float *fltp
; };
43 struct { double *dblp
; };
44 inputf(format
,arg1
,arg2
,arg3
)
47 register char *fp
, *cp
, cc
;
49 int fld
, val
, wv
, dv
, radix
;
50 char formc
, negflg
, negexp
, *fsp
, *scp
;
51 static char scbuf
[SCBLEN
], fldsep
[10];
56 scp
= scbuf
; /* init static string pointer */
58 while ((cc
= *fp
++) && cc
!= '%') putchar(cc
);
61 fld
= 0; /* used as return value when error found */
64 wv
= 0; dv
= 0; /* init w.d fields */
65 while (numeric(cc
= *fp
++)) wv
= wv
*10 + cc
- '0';
67 while (numeric(cc
= *fp
++)) dv
= dv
*10 + cc
- '0';
68 if (!wv
) wv
--; if (!dv
) dv
--; /* zero --> minus one */
69 formc
= cc
; /* save format character */
70 fsp
= cp
= fldsep
; /* collect terminators */
77 if (!*fsp
) fsp
= DFTSEP
;
88 while ((cc
= NEXTCHR
) && (cc
== ' ' || cc
== '-') && --wv
)
89 if (cc
== '-') negflg
++;
90 if (!cc
) return (fld
); /* return error if eof found */
91 if (formc
== 'i' && cc
== '0') radix
= 8;
94 val
= val
*radix
+ cc
- '0';
95 } else if (any(cc
,fsp
))
97 } while (--wv
&& (cc
= NEXTCHR
));
98 if (negflg
) val
= -val
;
109 val
= scbuf
+ SCBLEN
- 1 - cp
; /* calc max. limit on input */
111 if ((dv
= val
) <= 0) return (fld
);
113 while ((cc
= NEXTCHR
) && cc
== ' ' && --wv
);
114 if (!cc
) return (fld
); /* return error if eof found */
116 if (any(cc
,fsp
)) break;
117 if (!dv
--) return (fld
); /* too big */
119 } while (--wv
&& (cc
= NEXTCHR
));
120 if (dv
|| formc
== 's') *cp
++ = 0;
121 if (formc
== 'c') break;
126 while ((cc
= NEXTCHR
) && cc
== ' ' && --wv
);
128 while (!any(cc
,fsp
) && --wv
&& (cc
= NEXTCHR
));
134 val
= 0; /* used for explicit exponent */
135 radix
= 0100000; /* used for decimal place count */
136 while ((cc
= NEXTCHR
) && (cc
== ' ' || cc
== '-') && --wv
)
137 if (cc
== '-') negflg
++;
138 if (!cc
) return (fld
); /* return error if eof found */
141 dval
= dval
*10. + (cc
-'0');
143 } else if (cc
== '.') {
146 } else if (any(cc
,fsp
)) break;
147 else if (cc
== 'e') {
149 while ((cc
= NEXTCHR
) && !numeric(cc
) && --wv
)
150 if (cc
== '-') negexp
++;
151 if (!cc
) return (fld
); /* return error if eof found */
154 val
= val
*10 + cc
-'0';
155 else if (any(cc
,fsp
)) break;
156 } while (--wv
&& (cc
= NEXTCHR
));
157 if (negexp
) val
= -val
;
160 } while (--wv
&& (cc
= NEXTCHR
));
161 if (dv
> 0) radix
= dv
;
162 if (radix
> 0) val
=- radix
;
164 while (--val
>= 0) dval
= dval
*10.;
166 while (++val
<= 0) dval
= dval
/10.;
167 if (negflg
) dval
= -dval
;
175 write(2,"bad format specification",20);
184 return (chr
>= '0' && chr
<=