Tail: Write a program that prints out the last few lines of a file. The program
ID: 3714182 • Letter: T
Question
Tail: Write a program that prints out the last few lines of a file. The program should be efficient, in that it seeks to near the end of the file, reads in a block of data, and then goes backwards until it finds the requested number of lines; at this point, it should print out those lines from beginning to the end of the file. To invoke the program, one should type: mytail -n file, where n is the number of lines at the end of the file to print.
Must be written in C
Useful interfaces: stat(), lseek(), open(), read(), close().
Explanation / Answer
Below is your code
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#define MAXSIZE 2049 /* Max length of each line */
void error(char*);
int check(char*);
int fgetline(FILE*, char*, int);
int main(int argc, char *argv[]) {
FILE *fp;
char *fname, c, **line, tmpline[MAXSIZE];
int lines, i, len, index=0, flag_turnover=0;;
switch(argc) {
case 2:
fname = argv[1];
lines = 10;
break;
case 3:
if (check(argv[1]))
lines = (-1)*atoi(argv[1]);
else
error(argv[0]);
fname = argv[2];
break;
default:
error(argv[0]);
break;
}
fp = fopen(fname, "r");
if (fp == NULL) {
fprintf(stderr, "%s: File does not exist. ", fname);
exit(2);
}
line = (char **) malloc(lines*sizeof(char*));
if (line == NULL) {
fprintf(stderr, "Out of Memory. ");
fclose(fp);
exit(-1);
}
while((len = fgetline(fp, tmpline, MAXSIZE)) != 0) {
if (flag_turnover == 1)
free(line[index]);
line[index] = (char *) malloc(len*sizeof(char)+1); /* +1 for */
if (line[index] == NULL) {
fprintf(stderr, "Out of Memory. ");
fclose(fp);
exit(-1);
}
strcpy(line[index++], tmpline);
if (index == lines) {
flag_turnover = 1;
index = 0;
}
}
fclose(fp); /* Close the file when inputs are done. */
if (flag_turnover == 0) {
for (i=0; i<index; ++i)
printf("%s", line[i]);
}
else {
for (i=index; i<lines; ++i)
printf("%s", line[i]);
for (i=0; i<index; ++i)
printf("%s", line[i]);
}
return 0;
}
void error(char *command) {
fprintf(stderr, "Usage: %s [-n] file ", command);
fprintf(stderr, "(print last n (=10) lines of file) ");
exit(1);
}
int check(char *argv) {
char c;
c = *(argv++);
if (c != '-')
return 0;
while ((c = *(argv++)) != '')
if (!isdigit(c))
return 0;
return 1;
}
int fgetline(FILE *file,char *s,int lim)
{
int c,i=0;
while (--lim > 0 && (c=fgetc(file)) != EOF && c != ' ')
s[i++] = c;
if (c == ' ')
s[i++] = c;
s[i] = '';
return i;
}
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.