Skip to content

Commit e102ec1

Browse files
committed
Initial commit.
1 parent 88c06dd commit e102ec1

File tree

2 files changed

+254
-0
lines changed

2 files changed

+254
-0
lines changed

chapter07/7-3.c

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
/*
2+
* Exercise 7-3. Revise minprintf to handle more of the other facilities of
3+
* printf.
4+
* Note: flags (excepts for left adjust) and variable width and length are not implemented.
5+
* By Faisal Saadatmand
6+
*/
7+
8+
#include <stdio.h>
9+
#include <stdarg.h>
10+
#include <ctype.h>
11+
#include <stdlib.h>
12+
#include <string.h>
13+
14+
#define MAXNUMB 20
15+
#define FLT_PRCISION 6
16+
#define FIELD_WIDTH 1
17+
18+
/* macros */
19+
#define PRINT_N(la,x,w,v, nc) (la) ? (nc += printf("%-*" # x, w, v)) : \
20+
(nc += printf("%*" #x, w, v))
21+
#define PRINT_D(la,x,w,p,v,nc) (la) ? (nc += printf("%-*.*" # x, w, p, v)) : \
22+
(nc += printf("%*.*" # x, w, p, v))
23+
24+
int minprintf(char *, ...);
25+
26+
/* minprintf: minimal printf with variable argument list */
27+
int minprintf(char *fmt, ...)
28+
{
29+
va_list ap; /* points to each unnamed arg in turn */
30+
char *p, *sval, number[MAXNUMB];
31+
int ival, i, width, precision, nchar = 0;
32+
double dval;
33+
unsigned uval;
34+
void *pval;
35+
int leftAdjust, *pival;
36+
37+
38+
va_start(ap, fmt); /* make ap point to 1st unnamed arg */
39+
40+
for (p = fmt; *p; p++) {
41+
42+
if (*p != '%') {
43+
putchar(*p);
44+
++nchar;
45+
continue;
46+
}
47+
48+
leftAdjust = 0;
49+
width = 1;
50+
precision = -1;
51+
52+
if (*++p == '-') {
53+
leftAdjust = 1; /* left adjust */
54+
++p;
55+
}
56+
57+
if (isdigit(*p)) { /* get width */
58+
for (i = 0; isdigit(*p) && i < MAXNUMB; i++)
59+
number[i] = *p++;
60+
number[i] = '\0';
61+
width = atoi(number);
62+
}
63+
if (*p == '.') {
64+
++p;
65+
for (i = 0; isdigit(*p) && i < MAXNUMB; i++) /* get precision pts */
66+
number[i] = *p++;
67+
number[i] = '\0';
68+
precision = atoi(number);
69+
}
70+
71+
switch (*p) {
72+
case 'd':
73+
ival = va_arg(ap, int);
74+
PRINT_N(leftAdjust, d, width, ival, nchar);
75+
break;
76+
case 'i':
77+
ival = va_arg(ap, int);
78+
PRINT_N(leftAdjust, i, width, ival, nchar);
79+
break;
80+
case 'o':
81+
uval = va_arg(ap, int);
82+
PRINT_N(leftAdjust, o, width, uval, nchar);
83+
break;
84+
case 'x':
85+
uval = va_arg(ap, int);
86+
PRINT_N(leftAdjust, x, width, uval, nchar);
87+
break;
88+
case 'X':
89+
uval = va_arg(ap, int);
90+
PRINT_N(leftAdjust, X, width, uval, nchar);
91+
break;
92+
case 'u':
93+
uval = va_arg(ap, int);
94+
PRINT_N(leftAdjust, u, width, uval, nchar);
95+
break;
96+
case 'c':
97+
ival = va_arg(ap, int);
98+
PRINT_N(leftAdjust, c, width, ival, nchar);
99+
break;
100+
case 's':
101+
sval = va_arg(ap, char *);
102+
if (precision < 0)
103+
precision = strlen(sval);
104+
PRINT_D(leftAdjust, s, width, precision, sval, nchar);
105+
break;
106+
case 'f':
107+
dval = va_arg(ap, double);
108+
if (precision < 0)
109+
precision = FLT_PRCISION;
110+
PRINT_D(leftAdjust, f, width, precision, dval, nchar);
111+
break;
112+
case 'e':
113+
dval = va_arg(ap, double);
114+
if (precision < 0)
115+
precision = FLT_PRCISION;
116+
PRINT_D(leftAdjust, e, width, precision, dval, nchar);
117+
break;
118+
case 'E':
119+
dval = va_arg(ap, double);
120+
if (precision < 0)
121+
precision = FLT_PRCISION;
122+
PRINT_D(leftAdjust, E, width, precision, dval, nchar);
123+
break;
124+
case 'g':
125+
dval = va_arg(ap, double);
126+
PRINT_N(leftAdjust, g, width, dval, nchar);
127+
break;
128+
case 'G':
129+
dval = va_arg(ap, double);
130+
PRINT_N(leftAdjust, G, width, dval, nchar);
131+
break;
132+
case 'p':
133+
pval = va_arg(ap, void *);
134+
PRINT_N(leftAdjust, p, width, pval, nchar);
135+
break;
136+
case 'n':
137+
pival = va_arg(ap, int *);
138+
*pival = nchar;
139+
break;
140+
default:
141+
putchar(*p);
142+
++nchar;
143+
break;
144+
}
145+
}
146+
va_end(ap); /* clean up when done */
147+
return nchar;
148+
}
149+
150+
int main(void)
151+
{
152+
minprintf("minprintf() output:\n");
153+
minprintf("%s\n", "hello, world");
154+
minprintf("%10s\n", "hello, world");
155+
minprintf("%.10s\n", "hello, world");
156+
minprintf("%-10s\n", "hello, world");
157+
minprintf("%.15s\n", "hello, world");
158+
minprintf("%-15s\n", "hello, world");
159+
minprintf("%15.10s\n", "hello, world");
160+
minprintf("%-15.10s\n", "hello, world");
161+
162+
printf("\n");
163+
164+
printf("printf() output:\n");
165+
printf("%s\n", "hello, world");
166+
printf("%10s\n", "hello, world");
167+
printf("%.10s\n", "hello, world");
168+
printf("%-10s\n", "hello, world");
169+
printf("%.15s\n", "hello, world");
170+
printf("%-15s\n", "hello, world");
171+
printf("%15.10s\n", "hello, world");
172+
printf("%-15.10s\n", "hello, world");
173+
return 0;
174+
}
175+
176+

chapter07/7-4.c

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
* Exercise 7-4. Write a private version of scanf analogous to minprintf from
3+
* the previous section.
4+
* By Faisal Saadatmand
5+
*/
6+
7+
#include <stdio.h>
8+
#include <stdarg.h>
9+
#include <ctype.h>
10+
11+
int minscanf(char *, ...);
12+
13+
int minscanf(char *format, ...)
14+
{
15+
va_list ap;
16+
char *p, *sval, *cval;
17+
int *ival;
18+
float *fval;
19+
unsigned *uval;
20+
int nchar = 0;
21+
22+
va_start(ap, format); /* make ap point to 1st unnamed arg */
23+
for (p = format; *p; p++) {
24+
if (*p != '%')
25+
continue;
26+
27+
switch (*++p) {
28+
case 'd':
29+
ival = va_arg(ap, int *);
30+
nchar += scanf("%d", ival);
31+
break;
32+
case 'i':
33+
ival = va_arg(ap, int *);
34+
nchar += scanf("%i", ival);
35+
break;
36+
case 'o':
37+
uval = va_arg(ap, unsigned *);
38+
nchar += scanf("%u", uval);
39+
break;
40+
case 'c':
41+
cval = va_arg(ap, char *);
42+
nchar += scanf("%c", cval);
43+
break;
44+
case 's':
45+
sval = va_arg(ap, char *);
46+
nchar += scanf("%s", sval);
47+
break;
48+
case 'e':
49+
fval = va_arg(ap, float *);
50+
nchar += scanf("%e", fval);
51+
break;
52+
case 'f':
53+
fval = va_arg(ap, float *);
54+
nchar += scanf("%f", fval);
55+
break;
56+
case 'g':
57+
fval = va_arg(ap, float *);
58+
nchar += scanf("%g", fval);
59+
break;
60+
default:
61+
break;
62+
}
63+
va_end(ap);
64+
}
65+
return nchar;
66+
}
67+
68+
int main(void) {
69+
int x, y, z;
70+
int nchar;
71+
72+
printf("Enter an integer: ");
73+
nchar = minscanf("%i %i %i", &x, &y, &z);
74+
printf("%i %i %i\n", x, y, z);
75+
printf("Number of elements: %i\n", nchar);
76+
77+
return 0;
78+
}

0 commit comments

Comments
 (0)