The C programming language (second edition,K&R) exercise(CHAPTER 5)

      E x c e r c i s e 5 − 1 Excercise\quad 5-1 Excercise51:输出如图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;
}

 
图1.

      E x c e r c i s e 5 − 2 Excercise\quad 5-2 Excercise52:输出如图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;
}

 
图2.

      E x c e r c i s e 5 − 3 Excercise\quad 5-3 Excercise53

#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 Excercise54

#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 Excercise55:输出如图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);	
	}
}
 
图3.

      E x c e r c i s e 5 − 6 Excercise\quad 5-6 Excercise56

#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 Excercise57


#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 Excercise58

/*
 * 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 Excercise59

/*
 * 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 Excercise510:输出如图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
  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qqssss121dfd

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值