Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

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;

}