CS201 Winter 2008 Assignment 1: Implementing the 'tail' utility, Assignments of Computer Science

Instructions for completing assignment 1 in the cs201 course during the winter 2008 semester. Students are required to write their own version of the 'tail' utility, which prints the last n lines of a file. The design and implementation details, including memory management and handling command-line arguments.

Typology: Assignments

Pre 2010

Uploaded on 08/18/2009

koofers-user-df9
koofers-user-df9 🇺🇸

9 documents

1 / 4

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
CS201 Winter 2008 Assignment 1 Due Jan 15, 2008
Exercise 5-13, K&R page 118
Write your own version of the tail utility, as specified in this problem.
Simplifications:
Your program will not be tested with extremely long lines of text, nor with
non-text files, so you do not have to deal with pathological input data.
You can pick a number, such as 4096, and assume all lines of text in the
file are shorter than that. However, your program must deal with long
files; i. e., many lines of text.
The program takes input only from its standard input, so you do not have
to open any files.
Some of the example code in the book uses their own input function
"getline," but you can use the library function fgets to read lines of text.
Requirements are specified below. These will be used by the grader in grading your
submission, so use them as guidelines in testing your program before submitting it.
Among some of the important requirements:
Your program must read the input file only once. That is, it cannot scan
through the file to count the lines and then read it again up to where it
wants to start printing.
Your program must store each line of text that it is going to print in an
array of bytes that is just long enough to hold that line. That is, not in a
two-dimensional array of fixed size.
Attacking the problem
The major design issue is how to store the data in memory. The example function
readlines on page 109 of K&R shows how to read lines from a file, allocate memory, and
store the data. To read a line from a file, you can use the library function fgets; you don't
have to duplicate the function getline from the book.
The twist for this problem is that we do not want to store the whole file, only the last N
lines. Here is a suggested way to do it. You can do it differently if you want to.
Once we know how many lines we need, let's say nlines, we can dynamically allocate an
array of nlines pointers to characters. As we read each line of text into a buffer, we can
dynamically allocate an array for that line of text, pointed to by one of our pointers. Here
is a suggested way to allocate an array of pointers to characters:
char **linearray;
...
if((linearray = calloc(nlines, sizeof(char *))) == 0){
fprintf(stderr, "Couldn't allocate array\n");
exit(1);
}
pf3
pf4

Partial preview of the text

Download CS201 Winter 2008 Assignment 1: Implementing the 'tail' utility and more Assignments Computer Science in PDF only on Docsity!

Exercise 5-13, K&R page 118 Write your own version of the tail utility, as specified in this problem.

Simplifications:

  • Your program will not be tested with extremely long lines of text, nor with non-text files, so you do not have to deal with pathological input data. You can pick a number, such as 4096, and assume all lines of text in the file are shorter than that. However, your program must deal with long files; i. e., many lines of text.
  • The program takes input only from its standard input, so you do not have to open any files.
  • Some of the example code in the book uses their own input function " getline ," but you can use the library function fgets to read lines of text.

Requirements are specified below. These will be used by the grader in grading your submission, so use them as guidelines in testing your program before submitting it. Among some of the important requirements:

  • Your program must read the input file only once. That is, it cannot scan through the file to count the lines and then read it again up to where it wants to start printing.
  • Your program must store each line of text that it is going to print in an array of bytes that is just long enough to hold that line. That is, not in a two-dimensional array of fixed size.

Attacking the problem

The major design issue is how to store the data in memory. The example function readlines on page 109 of K&R shows how to read lines from a file, allocate memory, and store the data. To read a line from a file, you can use the library function fgets ; you don't have to duplicate the function getline from the book.

The twist for this problem is that we do not want to store the whole file, only the last N lines. Here is a suggested way to do it. You can do it differently if you want to.

Once we know how many lines we need, let's say nlines , we can dynamically allocate an array of nlines pointers to characters. As we read each line of text into a buffer, we can dynamically allocate an array for that line of text, pointed to by one of our pointers. Here is a suggested way to allocate an array of pointers to characters:

char **linearray; ...

if((linearray = calloc(nlines, sizeof(char *))) == 0){ fprintf(stderr, "Couldn't allocate array\n"); exit(1); }

Now we will read the file into a buffer line by line, and for each line we will allocate an array of bytes with one of our linearray[i] pointing to it, and then copy the line of text into that array. Since the file may have more than nlines, this will have to be a circular list. Each time we want to assign a member of linearray to a new line, we need to make sure it doesn't already point to something, and if so, free that thing in order to avoid a memory leak.

Here is an example for how you might allocate the memory for a line of text and copy it there. Assume the line has been read from the file into a buffer called buf , and we have determined that the length of the line is len.

if((linearray[curlineptr] = malloc(len+1)) == 0){ fprintf(stderr, "Couldn't allocate string\n"); exit(1); } strcpy(linearray[curlineptr], buf);

Once we've solved the major design issues, the first thing the program has to do is to decide whether there is a command line argument. If you don't know how to use argc and argv , see section 5.10 of K&R. You need to bypass the minus sign on the argument, and then you can use the library function strtol to convert the string to an integer.

Finally, once the file has been read, you must print the correct lines. You can use puts or printf to print a line. This is a question of keeping the bookkeeping straight in your

circular list of pointers, knowing where to begin and when to stop. In case the file is actually shorter than nlines , it's necessary to stop at the actual end of the file.

Deliverables

Please read the Deliverables shown on the homework page.

Grading Criteria

The assignment is worth a total of 50 points. Each item below indicates attributes the assignment should have, and points are deducted as shown from 50 accordingly if those attributes are lacking.

Assignment submitted on time (50 points)

Assignment turned in correctly (up to 5 points each bullet)

  • Emailed to the correct email address
  • Readable, understandable code. Variable names should tell what the variables are, and the logic of the code should be readable, not convoluted.
  • Blocks of code in braces are indented using tabs or at least 4 spaces.
  • Use of variables, defined constants, and operators such as "sizeof" rather than literals
  • Use of local variables wherever possible, rather than globals or statics
  • Output of the program is just what is specified, no debug messages, no greetings or other unnecessary messages except as specified in the problem. When input from the keyboard is called for, it's OK to print a message to prompt the user.
  • On errors, error messages are written to stderr rather than stdout.
  • Error checking should be done after every system call or library call except things like printf/scanf.
  • Comments indicate what is not obvious from the code itself. Each function should be headed by a brief comment saying what it does. The comment should not tell the data types of arguments or return value, because the function declaration itself does that. The comment should not tell where the function is called from, because that might change. The comment should tell any side effects the function has, other than its return value.
  • It is not necessary to comment the majority of lines of code; only things that really could use some explanation.