E x c e r c i s e 5 − 1 Excercise\quad 5-1 Excercise5−1:输出如图1所示。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int getint(int *pn);
/* reverse Polish calculator */
int main()
{
int num=0;
int ret=0;
ret=getint(&num);
printf("ret=%d\n",ret);
printf("num=%d\n",num);
ret=getint(&num);
printf("ret=%d\n",ret);
printf("num=%d\n",num);
ret=getint(&num);
printf("ret=%d\n",ret);
printf("num=%d\n",num);
ret=getint(&num);
printf("ret=%d\n",ret);
printf("num=%d\n",num);
return 0;
}
#include <ctype.h>
int getch(void);
void ungetch(int);
/* getint: get next integer from input to *pn */
int getint(int *pn)
{
int c, sign;
while (isspace(c = getch())); /* skip white space */
if (!isdigit(c) && c != EOF && c != '+' && c != '-')
{
ungetch(c);
return 0; /* it's not a number */
}
sign=(c=='-') ? -1 : 1 ;
if((c == '+')||(c == '-'))
{
c = getch();
if (!isdigit(c))
{
ungetch(c);
return 0; /* it's not a number */
}
}
for(*pn=0;isdigit(c);c = getch())
{
*pn=10 * (*pn) +(c - '0');
}
(*pn) *=sign;
if (c != EOF)
{
ungetch(c);
}
return c;
}
#define BUFSIZE 100
char buf[BUFSIZE]; /* buffer for ungetch */
int bufp = 0; /* next free position 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;
}
E x c e r c i s e 5 − 2 Excercise\quad 5-2 Excercise5−2:输出如图2所示。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int getfloat(float *pn);
/* reverse Polish calculator */
int main()
{
float num=0;
int ret=0;
ret=getfloat(&num);
printf("ret=%d\n",ret);
printf("num=%8g\n",num);
ret=getfloat(&num);
printf("ret=%d\n",ret);
printf("num=%8g\n",num);
ret=getfloat(&num);
printf("ret=%d\n",ret);
printf("num=%8g\n",num);
ret=getfloat(&num);
printf("ret=%d\n",ret);
printf("num=%8g\n",num);
return 0;
}
#include <ctype.h>
int getch(void);
void ungetch(int);
/* getint: get next integer from input to *pn */
int getfloat(float *pn)
{
int c,sign;
float power=1.0;
while (isspace(c = getch())); /* skip white space */
if (!isdigit(c) && c != EOF && c != '+' && c != '-')
{
ungetch(c);
return 0; /* it's not a number */
}
sign=(c=='-') ? -1 : 1 ;
if((c == '+')||(c == '-'))
{
c = getch();
if (!isdigit(c))
{
if (c==EOF)
{
return EOF;
}
ungetch(c);
return 0; /* it's not a number */
}
}
/* collect integer part */
for(*pn=0.0;isdigit(c);c = getch())
{
*pn=10.0 * (*pn) +(c - '0');
}
/* collect fraction part */
if (c == '.')
{
c = getch();
for(power=1.0;isdigit(c);c = getch())
{
*pn=10.0 * (*pn)+(c-'0');
power *=10.0;
}
}
(*pn) =(((*pn) * sign)/power);
if (c != EOF)
{
ungetch(c);
}
return c;
}
#define BUFSIZE 100
char buf[BUFSIZE]; /* buffer for ungetch */
int bufp = 0; /* next free position 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;
}
E x c e r c i s e 5 − 3 Excercise\quad 5-3 Excercise5−3:
#include <stdio.h>
void strcat_mysef(char *s,char *t);
int main()
{
char s[100]="This is strings ";
char t[20]="concatenating";
printf("original s=%s\n",s);
strcat_mysef(s,t);
printf("s=%s\n",s);
return 0;
}
/* strcat_mysef: concatenate t to end of s; s must be big enough */
void strcat_mysef(char *s,char *t)
{
while (*s++); /* find end of s */
s--;
while (*s++ = *t++); /* copy t */
return;
}
E x c e r c i s e 5 − 4 Excercise\quad 5-4 Excercise5−4:
#include <stdio.h>
#include <string.h>
int strend_mysef(char *s,char *t);
int main()
{
char s[100]="This is strings";
char t1[20]="strings";
char t2[20]="string";
printf("%d\n",strend_mysef(s,t1));
printf("%d\n",strend_mysef(s,t2));
return 0;
}
int strend_mysef(char *s,char *t)
{
int i,j;
i=strlen(s);
j=strlen(t);
s=s+i;
t=t+j;
while (*(--s) == *(--t) )
{
i--;
j--;
}
if(j==0)
{
return 1;
}
else
{
return 0;
}
}
E x c e r c i s e 5 − 5 Excercise\quad 5-5 Excercise5−5:输出如图3所示
#include <stdio.h>
#include <string.h>
char * strncpy_mysef(char *s,char *t,int n);
char * strncat_mysef(char *s,char *t,int n);
int strncmp_mysef(char *s,char *t,int n);
int main()
{
char t[20]="This is strncpy";
char s01[20]={
0};
char s02[20]={
0};
char s03[20]={
0};
printf("s01=%s\n",strncpy_mysef(s01,t,14));
printf("s02=%s\n",strncpy_mysef(s02,t,15));
printf("s03=%s\n",strncpy_mysef(s03,t,16));
printf("**********************************\n");
char s11[20]="This is ";
char s12[20]="This is ";
char s13[20]="This is ";
char t11[20]="strncpy";
char t12[20]="strncpy";
char t13[20]="strncpy";
printf("s11=%s\n",strncat_mysef(s11,t11,4));
printf("s12=%s\n",strncat_mysef(s12,t12,7));
printf("s13=%s\n",strncat_mysef(s13,t13,10));
printf("**********************************\n");
char s21[20]="str";
char s22[20]="strncpy";
char s23[20]="strncpy";
char t21[20]="strncpy";
char t22[20]="strncpy";
char t23[20]="strn";
printf("result is=%d\n",strncmp_mysef(s21,t21,4));
printf("result is=%d\n",strncmp_mysef(s22,t22,7));
printf("result is=%d\n",strncmp_mysef(s23,t23,10));
return 0;
}
char * strncpy_mysef(char *s,char *t,int n)
{
int i;
char * temp=s;
i = 0;
while ( (i<n) && ((*s = *t) != '\0') )
{
s++;
t++;
i++;
}
if(i==n)
{
*s = '\0';
}
return temp;
}
char * strncat_mysef(char *s,char *t,int n)
{
int i= 0;
char * temp=s;
while (*s++); /* find end of s */
s--;
while ( (i<n) && ((*s = *t) != '\0') )
{
s++;
t++;
i++;
}
if(i==n)
{
*s = '\0';
}
return temp;
}
int strncmp_mysef(char *s,char *t,int n)
{
int i= 0;
char * temp=s;
while ( (i<n) && ((*s) != '\0') && ((*t)!= '\0') && (*s == *t) )
{
s++;
t++;
i++;
}
if(i==n)
{
return 0;
}
else
{
return (*s)-(*t);
}
}
E x c e r c i s e 5 − 6 Excercise\quad 5-6 Excercise5−6:
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include <string.h>
#include <ctype.h>
/* atoi: convert s to integer*/
int atoi_myself(char *s)
{
int n=0;
int sign=0;
/* skip white space */
while(*s++==' ');
sign = (*s == '-') ? -1 : 1;
if (*s == '+' || *s == '-') /* skip sign */
s++;
while(isdigit(*s))
{
n = 10 * n + (*s++ - '0');
}
return sign * n;
}
void reverse(char *s)
{
char * e=s;
char c=0;
while(*e++);
--e;
--e;
while(s<e)
{
c = *(s);
*(s) = *(e);
*(e) = c;
s++;
e--;
}
}
void itoa_myself(int n, char *s)
{
int i, sign;
sign = n;
char *temp=s;
i = 0;
do
{
*s++ = abs(n % 10) + '0';
} while ( n /= 10 );
if (sign < 0)
*s++ = '-';
*s = '\0';
reverse(temp);
}
/* strindex: return index of t in s, -1 if none */
int strindex(char *s, char *t)
{
int tlen, count;
char *p, *q, *r;
q = t;
while(*q++);
q--;
tlen = q-t;
for(p = s; *p ; p++)
{
count = 0;
r = p;
for(q = t; *q ; q++, r++)
{
if(*r == *q)
count++;
else
break;
}
if(count == tlen)
return (int)(p-s);
}
return -1;
}
int getline(char *s, int lim)
{
int c;
char *original = s;
while (--lim > 0 && (c=getchar()) != EOF && c != '\n')
*s++ = c;
if (c == '\n')
*s++ = c;
*s = '\0';
return s - original;
}
#define NUMBER '0' /* for getop: signal that a number was found */
#define BUFSIZE 100 /* for ungetch and buf variable */
char buf[BUFSIZE]; /* for ungetch, getch: holds char buffer */
int bufp = 0; /* for ungetch, getch: next free position in buf */
int getch(void)
{
return (bufp > 0) ? buf[--bufp] : getchar();
}
void ungetch(int c)
{
if (bufp >= BUFSIZE)
printf("ungetch: too many characters\n");
else
buf[bufp++] = c;
}
int getop(char *s)
{
int c;
while ((*s = c = getch()) == ' ' || c == '\t');
*(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';
if (c != EOF)
ungetch(c);
return NUMBER;
}
int main()
{
char line[100];
char buffer[100];
char s[100]="This is strindex";
char t[100]=" st";
int line_len=0;
printf("INT_MIN: %d\n", INT_MIN);
itoa_myself(INT_MIN, buffer);
printf("Buffer : %s\n", buffer);
printf("Buffer to int= %d\n", atoi_myself(buffer));
printf("index of string t is %d\n", strindex(s,t));
line_len=getline(line, 100);
printf("line is %s, length is %d\n", line,line_len);
return 0;
}
E x c e r c i s e 5 − 7 Excercise\quad 5-7 Excercise5−7:
#include <stdio.h>
#include <string.h>
#define MAXLINES (50 )
#define MAXLEN (100 )
char *lineptr[MAXLINES];
int readlines(char *lineptr[], int maxlines, char *ls);
void writelines(char *lineptr[], int nlines);
void qsort(char *lineptr[], int left, int right);
int main()
{
int nlines;
/* array for storing all lines */
char linestore[MAXLINES * MAXLEN];
/* myreadlines will pass an extra parameter linestore for storing all the input lines */
if ((nlines = readlines(lineptr, MAXLINES, linestore)) >= 0)
{
qsort(lineptr, 0, nlines-1);
writelines(lineptr, nlines);
return 0;
}
else
{
printf("error: input too big to sort\n");
return 1;
}
}
/* getline: read a line into s, return length */
int getline(char s[], int lim)
{
int c, i;
for (i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; i++)
s[i] = c;
if (c == '\n')
{
s[i++] = c;
}
s[i] = '\0';
if(i==0)
{
return 0;
}
else
{
return (i+1);
}
}
/* readlines : read input lines */
int readlines(char *lineptr[], int maxlines, char *ls)
{
int len, nlines;
char *p, line[MAXLEN];
nlines = 0;
p = ls;
while ((len = getline(line, MAXLEN)) > 0)
{
/* The line below will check to make sure adding the nextline will not exceed MAXSTORE */
if (nlines >= maxlines || (strlen(ls) + len) > (MAXLINES * MAXLEN))
return -1;
else
{
strcpy(p, line);
lineptr[nlines++] = p;
p += len; /* point p to next empty position */
}
}
return nlines;
}
/* writelines: write output lines */
void writelines(char *lineptr[], int nlines)
{
while (nlines-- > 0)
printf("%s\n", *lineptr++);
}
/* swap: interchange v[i] and v[j] */
void swap(char *v[], int i, int j)
{
char *temp;
temp = v[i];
v[i] = v[j];
v[j] = temp;
}
/* qsort: sort v[left] ...v[right] into increasing order */
void qsort(char *v[], int left, int right)
{
int i, last;
/* do nothing if array contains fewer than two elements */
if (left >= right)
return;
swap(v, left, (left + right)/2);
last = left;
for (i = left+1; i <= right; i++)
if (strcmp(v[i], v[left]) < 0)
swap(v, ++last, i);
swap(v, left, last);
qsort(v, left, last-1);
qsort(v, last+1, right);
}
E x c e r c i s e 5 − 8 Excercise\quad 5-8 Excercise5−8:
/*
* A solution to exercise 5-8 in K&R2, page 112:
*
* There is no error checking in day_of_year or month_day. Remedy
* this defect.
*
* The error to check for is invalid argument values. That is simple, what's
* hard is deciding what to do in case of error. In the real world, I would
* use the assert macro from assert.h, but in this solution I take the
* approach of returning -1 instead. This is more work for the caller, of
* course.
*
* I have selected the year 1752 as the lowest allowed year, because that
* is when Great Britain switched to the Gregorian calendar, and the leap
* year validation is valid only for the Gregorian calendar.
*
* Lars Wirzenius <liw@iki.fi>
*/
#include <stdio.h>
static char daytab[2][13] = {
{
0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{
0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
};
/* day_of_year: set day of year from month & day */
int day_of_year(int year, int month, int day)
{
int i, leap;
if (year < 1752 || month < 1 || month > 12 || day < 1 || day > 31)
return -1;
leap = (year%4 == 0 && year%100 != 0) || year%400 == 0;
if (day > daytab[leap][month])
return -1;
for (i = 1; i < month; i++)
day += daytab[leap][i];
return day;
}
/* month_day: set month, day from day of year */
int month_day(int year, int yearday, int *pmonth, int *pday)
{
int i, leap;
if (year < 1752 || yearday < 1)
return -1;
leap = (year%4 == 0 && year%100 != 0) || year%400 == 0;
if ((leap && yearday > 366) || (!leap && yearday > 365))
return -1;
for (i = 1; yearday > daytab[leap][i]; i++)
yearday -= daytab[leap][i];
*pmonth = i;
*pday = yearday;
return 0;
}
/* main: test day_of_year and month_day */
int main(void)
{
int year, month, day, yearday;
for (year = 1970; year <= 2000; ++year)
{
for (yearday = 1; yearday < 366; ++yearday)
{
if (month_day(year, yearday, &month, &day) == -1)
{
printf("month_day failed: %d %d\n",year, yearday);
}
else if (day_of_year(year, month, day) != yearday)
{
printf("bad result: %d %d\n", year, yearday);
printf("month = %d, day = %d\n", month, day);
}
}
}
return 0;
}
E x c e r c i s e 5 − 9 Excercise\quad 5-9 Excercise5−9:
/*
* A solution to exercise 5-8 in K&R2, page 112:
*
* There is no error checking in day_of_year or month_day. Remedy
* this defect.
*
* The error to check for is invalid argument values. That is simple, what's
* hard is deciding what to do in case of error. In the real world, I would
* use the assert macro from assert.h, but in this solution I take the
* approach of returning -1 instead. This is more work for the caller, of
* course.
*
* I have selected the year 1752 as the lowest allowed year, because that
* is when Great Britain switched to the Gregorian calendar, and the leap
* year validation is valid only for the Gregorian calendar.
*
* Lars Wirzenius <liw@iki.fi>
*/
#include <stdio.h>
static char daytab[2][13] =
{
{
0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{
0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
};
/* day_of_year: set day of year from month & day */
int day_of_year(int year, int month, int day)
{
int i, leap;
if (year < 1752 || month < 1 || month > 12 || day < 1 || day > 31)
return -1;
leap = (year%4 == 0 && year%100 != 0) || year%400 == 0;
if (day > (*(*(daytab+leap)+month)))
return -1;
for (i = 1; i < month; i++)
day += (*(*(daytab+leap)+i));
return day;
}
/* month_day: set month, day from day of year */
int month_day(int year, int yearday, int *pmonth, int *pday)
{
int i, leap;
if (year < 1752 || yearday < 1)
return -1;
leap = (year%4 == 0 && year%100 != 0) || year%400 == 0;
if ((leap && yearday > 366) || (!leap && yearday > 365))
return -1;
for (i = 1; yearday > (*(*(daytab+leap)+i)); i++)
yearday -= (*(*(daytab+leap)+i));
*pmonth = i;
*pday = yearday;
return 0;
}
/* main: test day_of_year and month_day */
int main(void)
{
int year, month, day, yearday;
printf("Day of year and month-day test start\n");
for (year = 1970; year <= 2000; ++year)
{
for (yearday = 1; yearday < 366; ++yearday)
{
if (month_day(year, yearday, &month, &day) == -1)
{
printf("month_day failed: %d %d\n",year, yearday);
}
else if (day_of_year(year, month, day) != yearday)
{
printf("bad result: %d %d\n", year, yearday);
printf("month = %d, day = %d\n", month, day);
}
}
}
printf("Day of year and month-day test end\n");
return 0;
}
E x c e r c i s e 5 − 10 Excercise\quad 5-10 Excercise5−10:输出如图4所示。
#include <stdio.h>
#include <stdlib.h> /* for atof() */
#include <math.h> /* for fmod() */
#include <ctype.h>
#define ERROR_FORMAT ('e')
#define MAXOP 100 /* max size of operand or operator */
#define NUMBER '0' /* signal that a number was found */
int getop(char * s,char * argv);
void push(double);
double pop(void);
void ViewStack(void);
/* reverse Polish calculator */
int main(int argc, char * argv[])
{
int type;
double op2;
char s[MAXOP];
char ** temp_argv=argv;
int i=0;
while(i<argc)
{
printf("Argument %d=%s\n", i,*temp_argv++);
i++;
}
printf("*************************************\n");
while (--argc)
{
type = getop(s,*++argv);
switch (type)
{
case NUMBER:
printf("NUMBER:\n");
push(atof(s));
ViewStack();
break;
case '+':
printf("+:\n");
push(pop() + pop());
ViewStack();
break