
Hello everyone,

Here are the tutorial notes for this week. Remember, feel free to contact me
if you have any questions about the material. (You don't have to email me
after your tutorial this week, but if there are any problems please let me
know about them.)

Reminders
=========

 - Assignment 2 is out, but due to a scheduled power outage in the Bahen
   building, CDF will be down from June 25-27. As a result, I've moved the
   deadline of A2 back a couple days. It's now due July 1, but I may move this
   to July 2 so it doesn't conflict with the Canada Day holiday. Check the
   website before your tutorial for details.

 - The midterm is scheduled for July 6, from 6:00-7:00pm in SF1105 (the
   lecture room). Please announce this information to your students so that
   they go to the correct room. There will be no tutorial on July 6, so
   each of you will have the week off.

 - Also, please announce these extra office hours to your students: Paul will
   be holding a lab/office hour on June 30 from 6:00-7:00pm in BA3234. I will
   also be extending my office hours on July 5 from 10:00-1:00pm.


Tutorial 5 Notes -- June 22
===========================

(1) Assignment 2

 - If you haven't looked over Assignment 2, please try to do so before your
   tutorial (the second part will be posted today). I expect there will be
   questions so take some time to answer as many as you can.

(2) More C examples

 - We have been continuing our discussion on C programming and, not
   surprisingly, there have been a lot of questions about pointers, strings,
   and memory allocation. This week I'd like you to present a few more
   examples to your students.

   (a) For the first example, you can present the following function that is
   supposed to be a naive string copy:

     char * my_string_copy(char *str1)
     {
         int i, l;
         char *str2;

         l = sizeof(str1);

         str2 = malloc(l);

         for (i = 0 ; i < l ; i++)
             str2[i] = str1[i];

         return(str2);
     }

   Ask your students what is wrong with this function, and ask them how they
   would fix it. (You can assume, for instance, that every non-NULL string
   passed to my_string_copy() will correctly end with a \0.)

   The purpose of this question is to get your students participating in the
   discussion as to why some changes are needed.

   Here are some points you can make:

       - sizeof() should be strlen()
       - the new statement "l = sizeof(str1)" should be protected by checking
         the pointer str1:
             if (str1 == NULL)   or   if (!str)
                 return(NULL);            return(NULL);
         since the call to strlen(str1) may cause a segmentation fault if str1
         is NULL.
       - the arguments to malloc() shouldn't be "l", but "l + 1" or
         "sizeof(char) * (l + 1)" (I've been encouraging them to get in
         the habit of using sizeof() for other datatypes). The extra "+1"
         includes space for the string terminator character.
       - the return value of malloc() should be checked. If it is NULL, the
         program should probably just display an error message and exit.
         Please stress to your students that it is important to check the
         return values of function/system calls (even when we don't do this in
         every example we give them).
       - after the for() loop a line like:
             str2[i] = '\0';
         can be added to ensure the string terminator is written to str2.

    Feel free to make other changes if you'd like to highlight some other
    points.

    (b) For the second example, ask the students to tell you what the output
    of the following lines of code would be (i.e., what is the length of
    each string):

         printf("%d\n", strlen("A test string"));
         printf("%d\n", strlen("A test\tstring\n"));
         printf("%d\n", strlen("A test\0string"));
         printf("%d\n", strlen("\"A test\"string"));
         printf("%d\n", strlen(""));
         printf("%d\n", strlen("\0"));

    The output should be:

         13
         14
         6
         14
         0
         0

    Some points to make:

       - The string terminator character does not count towards the length of
         the string as far as strlen() is concerned.
       - Escaped characters (e.g., \", \n, \t, \0) count as a single
         character. You may also want to mention that there are other escaped
         characters as well (e.g., \\ - backslash, \b - backspace, \v -
         vertical tab, etc.).

    (c) The final example involves reading and writing with files. (This
    program is adapted from an example I put online for the students, but
    won't cover in lecture.) It will also be good for the students to see an
    example that uses command-line arguments.

        #include <stdio.h>
        #include <stdlib.h>

        int main(int argc, char **argv)
        {
            int c;
            FILE *f_read, *f_write;

            if (argc != 3) {
                fprintf(stderr, "Usage: %s input-file output-file\n",
                        argv[0]);
                exit(1);
            }

            f_read = fopen(argv[1], "r");
            if (!f_read) {
                fprintf(stderr, "Error opening input file!\n");
                exit(1);
            }

            f_write = fopen(argv[2], "w");
            if (!f_write) {
                fprintf(stderr, "Error opening output file!\n");
                exit(1);
            }

            while((c = fgetc(f_read)) != EOF)
                fputc(c, f_write);

            fclose(f_read);
            fclose(f_write);

            return(0);
        }

    Basically, the program tries to open a pair of files (an input file and an
    output file) as specified on the command line. The program then reads the
    contents of the input file one character at a time, and writes this
    information to the output file. This continues until the end of the input
    file is reached, when the two files are closed.

    Here are a few points you can make:

        - Once again, it is important to check the return values of function
          calls, e.g., fopen() and fgetc().
        - EOF is a special defined value that signifies end-of-file.
        - It is considered good coding practice to close all files that your
          program opens (even though the system will do this for you when your
          program ends).
        - This example should be of help for Assignment 2, if the students
          haven't figured out the file I/O component yet.

(3) Debuggers

    This week, simply encourage your students to use a debugger (e.g., gdb or
    DDD) with their C programs, especially if they can't figure out why their
    program is generating a segmentation faults. You can point them to:

        http://www.cdf.utoronto.ca/~csc209h/winter/tut/gdb_tutorial.html

    for a gdb tutorial, or

        http://www.cs.toronto.edu/~reid/csc209/01f/notes/debugging.html

    for a DDD tutorial. (I'll put these links on the course webpage.)

