CS360 Exam #1. October 25, 1996

  • Jim Plank
  • 50 points total. Do all questions.

    Question 1 (10 points)

    Part 1 (5 points)

    Explain why you should use the standard I/O library rather than the file I/O system calls for reading lines of text from a file. (Don't just give a one word answer -- explain it).

    Part 2 (5 points)

    If you are reading one character at a time from a file, why is it better to use getchar() or fgetc() rather than fread()?

    Question 2 (12 points)

    Convert the following C code into (unoptimized) assembler. Use only registers r0 and r1 (plus of course the stack and frame pointers).
    main(int argc, char **argv)
    {
      int i, j;
    
      j = 0;
      while(argc > 0) {
        i = j + 5;
        j = main(b(j), i-1);
      }
    }
    

    Question 3 (14 points)

    Part 1 (12 points)

    Write the program parent that prints the name of the parent directory of the current directory. In other words, the following should be the output of parent: You may not use system(), getcwd() or getenv().
    UNIX> cd /mahogany/homes/plank
    UNIX> pwd
    /mahogany/homes/plank
    UNIX> parent
    plank
    UNIX> cd papers
    UNIX> pwd
    /mahogany/homes/plank/papers
    UNIX> parent
    papers
    UNIX>
    
    See the last page of this test for prototypes of C library calls and system calls that may be helpful.

    Part 2 (2 points)

    What will be the output of:
    UNIX> cd /
    UNIX> parent
    

    Question 4 (14 points)

    This question concerns the program printword. This program takes a file on standard input, and sorts the words. For each word, it prints out the line numbers (sorted) that contain the word. It skips lines whose first word starts with the '#' character. It should not print out a line number twice for the same word.

    Thus, for the following file:

    UNIX> cat geh
    # Beginning
    I am Sam
    I am Sam
    Sam I am
       That Sam I am   That Sam I am    I do not like that Sam I am
     # end
    UNIX> 
    
    The output of the program should be the following:
    UNIX> wordline < geh
    I: 2, 3, 4, 5
    Sam: 2, 3, 4, 5
    That: 5
    am: 2, 3, 4, 5
    do: 5
    like: 5
    not: 5
    that: 5
    UNIX>
    
    Now, behold the following code for printword:
    #include < stdio.h >
    #include "fields.h"
    #include "rb.h"
    
    main()
    {
      IS is;
      Rb_node t, tmp;
      char *s;
      int i, fnd;
    
      t = make_rb();
      is = new_inputstruct(NULL);
    
      while(get_line(is) > 0) {
        if (is->text1[0] != '#') {
          for (i = 0; i < is->NF; i++) {
            tmp = rb_find_key_n(t, is->fields[i], &fnd);
            if (!fnd || is->line != (int) (tmp->v.val)) {
              rb_insert(t, is->fields[i], (char *) (is->line));
            }
          }
        }
      }
    
      s = NULL;
      rb_traverse(tmp, t) {
        if (strcmp(s, tmp->k.key) != 0) {
          if (s != NULL) printf("\n");
          printf("%s: %d", tmp->k.key, (int) (tmp->v.val));
        } else {
          printf(", %d", (int) (tmp->v.val));
        }
        s = tmp->k.key;
      }
      printf("\n");
    }
    
    There are five bugs in this program. By ``bug'', I mean that they will cause incorrect output (or core dumpage), not inefficiency. Four of them are simple and can be fixed within the line that they occur. The fifth is a disign flaw in the program. For each of these bugs: Note -- none of the bugs are syntax/compiler errors. This code will compile just fine. They are all functional errors.

    Again, prototypes of relevant C functions and structs are at the end of the test.