练习5-13 编写程序tail,将其输入中的最后n行打印出来。默认情况下,n的值为10,但可以通过一个可选参数改变n的值

来源:互联网 发布:宋宁宗 知乎 编辑:程序博客网 时间:2024/06/02 03:48

若行数小于n,则全部打印,若行数大于n则打印最后n行,使用条件if(nlines<=n || i>=nlines-n)判断第i行是否打印。

#include <stdio.h>#include <stdlib.h>#include <string.h>#define MAXLINES 5000char *lineptr[MAXLINES];int readlines(char *lineptr[],int nlines);main(int argc,char *argv[]){    int i,n,nlines;    if(argc>1 && (*argv[1]='-'))        n=atoi(&(*++argv)[1]);    else        n=10;    nlines=readlines(lineptr,MAXLINES);    for(i=0;i<nlines;i++)        if(nlines<=n || i>=nlines-n)            printf("%s\n",lineptr[i]);}#define MAXLEN 1000int getline(char *,int);char *alloc(int);int readlines(char *lineptr[],int maxlines){    int len,nlines;    char *p,line[MAXLEN];    nlines=0;    while((len=getline(line,MAXLEN))>0){        if(nlines>MAXLINES || (p=alloc(len))==NULL)            return -1;        else{            line[len-1]='\0';            strcpy(p,line);            lineptr[nlines++]=p;        }    }    return nlines;}int getline(char *s,int lim){    int c;    char *t=s;    while(--lim>0 &&(c=getchar())!=EOF && c!='\n')        *s++=c;    if(c=='\n')        *s++=c;    *s='\0';    return s-t;}#define ALLOCSIZE 10000static char allocbuf[ALLOCSIZE];static char *allocp=allocbuf;char *alloc(int n){    if(allocbuf+ALLOCSIZE-allocp>=n){        allocp+=n;        return allocp-n;    }    else        return 0;}

答案中

bufend=buf+LINES*MAXLEN

指针超出数组1位(指针越界),会有怎样结果?测试:

#include <stdio.h>main(){    char a[3];    char *p;    a[0]='a';    a[1]='b';    a[2]='\0';    printf("%s\n",a);    p=a+1;    printf("%s\n",p);    p=a+2;    printf("%s\n",p);    p=a+3;    printf("%s\n",p);}

运行输出:
这里写图片描述
若程序数组下标赋值起始位置不对:

#include <stdio.h>main(){    char a[3];    char *p;    a[1]='a';    a[2]='b';    a[3]='\0';    printf("%s\n",a);    p=a+1;    printf("%s\n",p);    p=a+2;    printf("%s\n",p);    p=a+3;    printf("%s\n",p);}

运行输出:
这里写图片描述

指针指向随机位置。

答案程序:

#include <stdio.h>#include <stdlib.h>#include <string.h>#define DEFLINES 10#define LINES    100#define MAXLEN   100void error(char *);int getline(char *,int);main(int argc,char *argv[]){    char *p;    char *buf,*bufend;    char line[MAXLEN];    char *lineptr[LINES];    int i,first,last,len,n,nlines;    if(argc==1)        n=DEFLINES;    else if(argc==2 && (*++argv)[0]=='-')        n=atoi(argv[0]+1);    else        error("usage: tail [-n]");    if(n<1||n>LINES)        n=LINES;    for(i=0;i<LINES;i++)        lineptr[i]=NULL;    if((p=buf=malloc(MAXLEN*LINES))==NULL)        error("tail: cannot allocate buf");    bufend=buf+MAXLEN*LINES;    last=0;    nlines=0;    while((len=getline(line,MAXLEN))>0){        if(p+len+1>=bufend)            p=buf;        strcpy(p,line);        lineptr[last]=p;        if(++last>=LINES)            last=0;        p+=len+1;        nlines++;    }    if(n>nlines)        n=nlines;    first=last-n;    if(first<0)        first+=LINES;//first=LINES-1-(n-last)+1    for(i=first;n-->0;i=(i+1)%LINES)        printf("%s",lineptr[i]);}void error(char *s){    printf("%s\n",s);    exit(1);}int getline(char *s,int lim){    int c;    char *t=s;    while(--lim>0 && (c=getchar())!=EOF && c!='\n')        *s++=c;    if(c=='\n')        *s++=c;    *s='\0';    return s-t;}
0 0