C程序设计语言里有一道习题是,tail -n
根据n的值打印,输入行的最后几行。默认打印10行,
我写了一个,代码如下,供大家交流讨论#include #include #define MAXLINES 1000 char *lineptr[MAXLINES]; int readlines(char *lineptr[],int lines); void writelines(char *lineptr[],int lines); int main(int argc,char *argv[]) { int lines; char str; int digit=0;
if( argc >1 ) { if((*++argv)[0] == '-' ) { while((str=*++argv[0])!='') if(str>='0' && str <='9') digit=digit*10+(str-'0'); else {digit=10; break;} } else digit=10; } else digit=10;
if( (lines=readlines(lineptr,MAXLINES) ) >= 0 ) { if(digit==10) { if( lines < digit) writelines(lineptr,0); else writelines(lineptr,lines-digit); } else if(lines writelines(lineptr,0); else writelines(lineptr,lines-digit); } return 0; } #define MAXLEN 1000 int getline(char *,int); char *alloc(int); int readlines(char *lineptr[],int maxline) { int nlines=0; int len; char *p,line[MAXLEN];
while( (len=getline(line,MAXLEN)) >0 ) { if(len>MAXLEN || (p=alloc(len))==NULL) return -1; else{ line[len-1]=''; strcpy(p,line); [nlines++]=p; } } return nlines; } /*void writelines(char *lineptr[],int begin ) {//writelines的另一种实现方式 char **ptr; for(ptr=lineptr+begin;ptr<=lineptr+lines-1;++ptr) printf("%s\n",*ptr); }*/ void writelines(char *lineptr[],int begin ) { lineptr+=begin;
while(*lineptr!=NULL) printf("%s\n",*lineptr++); } int getline(char line[],int maxline) {
int c; int i=0;
while( --maxline > 0 && (c=getchar())!=EOF && c!='\n') line[i++]=c; if(c=='\n') line[i++]='\n'; line[i]=''; return i; } #define ALLOCSIZE 10000 static char allocbuf[ALLOCSIZE]; static char *allocp=allocbuf; char *alloc(int n) { if(allocbuf+ALLOCSIZE-allocp>=n) { allocp+=n; return allocp-n; } return NULL; } listli的代码:支持文件名,比较通用的说 #include #include
#define LINE 1000 #define SIZE 512
struct lines { int chs; }info[LINE]; static int total; /*total lines*/ static FILE *fp; static int n; /*the last n lines to be read*/
void printUsage() { fprintf(stderr, "Usage: tail [-n] [filename]\n"); exit(1); }
int cmdParse(int argc, char **argv) { if (argc == 1) { fp = stdin; n = 10; } else if(argc == 2) { if (argv[1][0] == '-') { n = atoi(&argv[1][1]); fp = stdin; } else { n = 10; fp = fopen(argv[1],"r"); } } else if(argc == 3) { n = atoi(&argv[1][1]); fp = fopen(argv[2],"r"); } else { printUsage(); } return n; }
void tail(int); int main(int argc,char **argv) {
cmdParse(argc,argv); char tembuf[SIZE]; int i ; for( i = 0; fgets(tembuf,sizeof tembuf,fp); ++i) { info[i].chs = strlen(tembuf); total++; } tail(n); while(fgets(tembuf,sizeof tembuf,fp)) fputs(tembuf,stdout); return 0; }
void tail(int n) { int tolen = 0; int i; for(i = total - n ; i < total ;++i) tolen += info[i].chs; fseek(fp,-tolen,SEEK_CUR); } |