Exercise 4-8
Suppose that there will never be more than one character of pushback. Modify getch and ungetch accordingly.
/* K&R Exercise 4-8 */
/*
written by Steven Huang
revised by ffffx0@gmail.com
*/
#include <stdio.h>
int buf = EOF; /* buffer for ungetch */
int getch(void) /* get a (possibly pushed back) character */
{
int temp = buf;
buf = EOF;
return temp==EOF ? (getchar()) : temp;
}
void ungetch(int c) /* push character back on input */
{
if(buf != EOF)
printf("ungetch: too many characters/n");
else
buf = c;
}
int main(void)
{
int c;
while ((c = getch()) != EOF) {
if (c == '/') {
putchar(c);
if ((c = getch()) == '*') {
ungetch('!');
}
}
putchar(c);
}
return 0;
}
/* K&R Exercise 4-8 */
/* written by ffffx0@gmail.com */
/* the simple solution is change BUFSIZE to 1 */
#include <stdio.h>
#define BUFSIZE 1
char buf[BUFSIZE]; /* buffer for ungetch */
int bufp = 0; /* next free postion in buf */
int getch(void) /* get a (possibly pushed back) character */
{
return bufp > 0 ? buf[--bufp] : getchar();
}
void ungetch(int c) /* push character back on input */
{
if(bufp >= BUFSIZE)
printf("ungetch: too many characters/n");
else
buf[bufp++] = c;
}
int main(void)
{
int c;
while ((c = getch()) != EOF) {
if (c == '/') {
putchar(c);
if ((c = getch()) == '*') {
ungetch('!');
}
}
putchar(c);
}
return 0;
}
Exercise 4-9
Our getch and ungetch do not handle a pushed-back EOF correctly. Decide what their properties ought to be if an EOF is pushed back, and then implement your design.
#include <stdio.h>
/* it's better to avoid this happening. */
#include <stdio.h>
#define BUFSIZE 1
char buf[BUFSIZE]; /* buffer for ungetch */
int bufp = 0; /* next free postion in buf */
int getch(void); /* get a (possibly pushed back) character */
void ungetch(int); /* push character back on input */
int main() {
int c;
/*ungetch('1');
ungetch('2'); */
ungetch(EOF); /* ungetch('!'); ungetch('4');*/
c= getch();
printf("%c/n", c);
c = getch();
printf("%c/n", c);
return 0;
}
int getch(void) /* get a (possibly pushed back) character */
{
if (bufp > 0) {
return buf[--bufp];
}
else
return getchar();
}
void ungetch(int c) /* push character back on input */
{
if(bufp >= BUFSIZE)
printf("ungetch: too many characters/n");
else if (c != EOF)
buf[bufp++] = c;
}
Exercise 4-10
An alternate organization uses getline to read an entire input line; this makes getch and ungetch unnecessary. Revise the calculator to use this approach.
Exercise 4-11
Modify getop so that it doesn't need to use ungetch. Hint: use an internal static variable.
/* getop: get next operator or numeric operand */
int getop(char *s)
{
int c;
static int buf = EOF;
if (buf == EOF || buf == ' ' || buf == '/t')
while ((*s = c = getch()) == ' ' || c == '/t')
;
else
*s = c = buf;
buf = EOF;
*(s + 1) = '/0';
if (!isdigit(c) && c != '.')
return c; /* not a number */
if (isdigit(c)) /* collect integer part */
while (isdigit(*++s = c = getch()))
;
if (c == '.') /* collect fraction part */
while (isdigit(*++s = c = getch()))
;
*++s = '/0';
buf = c;
return NUMBER;
}
Exercise 4-12
Adapt the ideas of printd to write a recursive version of itoa ; that is, convert an integer into a string by calling a recursive routine.
#include <stdio.h>
/* itoa_recursive: convert an integer to a string.
use recrusive method */
void itoa_recursive(int n, char s[]);
int main() {
int n = -123456;
char num[64]={0};
printf("%d/n", strlen(num));
itoa_recursive(n ,num);
printf("%s/n", num);
return 0;
}
void itoa_recursive(int n, char s[]) {
int i;
if (n < 0) {
i = strlen(s);
s[i++] = '-';
s[i] = '/0';
n = -n;
}
if (n / 10)
itoa_recursive(n/10, s);
i = strlen(s);
s[i++] = abs(n % 10) + '0';
s[i] = '/0';
}
Exercise 4-13
Write a recursive version of the function reverse(s) , which reverses the string s in place.
#include <stdio.h>
/* reverse_recursive: reverse string s in place */
void reverse_recursive(char[], int, int);
int main() {
char s[] = "reverse_recursive";
printf("before reverse: %s/n", s);
reverse_recursive(s, 0, strlen(s)-1);
printf("before reverse: %s/n", s);
return 0;
}
void reverse_recursive(char s[], int p1, int p2) {
int temp;
if (p1 < p2) {
temp = s[p1];
s[p1] = s[p2];
s[p2] = temp;
reverse_recursive(s, p1+1, p2-1);
}
else return;
}
Exercise 4-14
Define a macro swap(t,x,y) that interchanges two arguments of type t . (Block structure will help.)
#include <stdio.h>
#define swap(t, x, y) /
do { /
t safe ## x ## y; /
safe ## x ## y = x; /
x = y; /
y = safe ## x ## y; /
} while (0)
int main() {
int x = 5, y = 8;
printf("before swap:/n");
printf("x = %d, y = %d/n", x, y);
printf("after swap:/n");
swap(int, x, y);
printf("x = %d, y = %d/n", x, y);
return 0;
}