Lab overview
Lab 01
Lab 02
Lab 03
Lab 04
Lab 05
Lab 06
Lab 07
Lab 08
Lab 09
Lab 10
Lab 11
Lab 12
Lab 13
Review

[Course home page]

CSC 209 lab 04 exercises, week of 31 May 2022

[solutions are available (requires teach.cs authentication)]

Attendance

As usual, please either run /u/csc209h/summer/present on the console of a lab workstation, or get the TA to record your attendance. Please do this first so that you don't forget.

Remember that you can check that your attendance has been recorded properly at https://wwwcgi.teach.cs.toronto.edu/~ajr/cgi-bin/auth/present (this will work immediately after the recording, whether the attendance was recorded by you or by the TA)


Problem 1: Simple first task

Create a "hello, world" program in C (it just outputs "hello, world") and compile it and make sure it runs properly.

Compile it with "gcc −Wall". You should always compile with "gcc −Wall".


Problem 2: rot13 (for credit)

Write a C program which implements the "rot13" transformation (which is an encryption and also the decryption): letters are "rotated" 13 places along the alphabet, and non-letters are copied unaltered.

So you add 13 to characters between 'a' and 'm' inclusive, as well as to characters between 'A' and 'M' inclusive; and you subtract 13 from characters between 'n' and 'z' inclusive, as well as from characters between 'N' and 'Z' inclusive.

Your program reads from the standard input with getchar() and writes to the standard output with putchar(). So you will probably want to begin with the "cat"-like program shown in lecture, which you can find in /u/csc209h/summer/pub/lab/04/cat.c

Remember that characters are just small integers in C, so for example 'a' is just an integer expression with value 97 (the ASCII character value), and 97 and 'a' can be used interchangeably (of course, you would use whichever one expressed your meaning most clearly — probably 'a').

Call your program rot13.c, and submit it for lab04 in the usual way.


Problem 3: Integer square root

Write an "integer square root" program which works by binary search: Read an integer from the standard input with scanf (don't print a prompt), and guess that its square root is half the number, and by squaring the guessed square root, go higher or lower using the usual binary search algorithm. The integer square root of n is the value x such that x² ≤ n < (x+1)².

3b) Write a loop in sh which uses your above program to find the largest integer whose integer square root is 12. (answer: 168)

3c) Modify your 3a program to print a prompt. Try it interactively. Then run your 3b shell script to demonstrate why we don't print prompts when writing software tools!


Problem 4: Separate compilation

Break your "hello, world" program ("simple first task" above) into two .c files. One of them contains the main(), and the other one contains a function which does the actual printing. You would compile with a command like "gcc −Wall main.c hello.c".

Make sure it compiles with no warnings or error messages, and performs exactly correctly (this is simple enough that you should be able to make it perfect).


Problem 5: "Add"

Write the "add" program, which takes no command-line arguments and simply adds together all of the numbers in its standard input. The input consists of free-format integers and should be read with scanf("%d",&x).

Note that scanf("%d",&x) returns 1 for a successful input; EOF (i.e. −1) for end-of-file; and 0 if you are trying to read non-numeric input. In the non-numeric-input case, you should write "add: non-numeric input\n" to the standard error and not write anything to the standard output.

Otherwise, you should write the total (and nothing else except a terminating \n) to the standard output.

Note that "add </dev/null" should produce the output "0".

To write to stderr, do this:

	fprintf(stderr, "add: non-numeric input\n");


Problem 6: For credit

Write a program which works as follows. This is not a very unix-tools type of program, but it exercises C arrays and pointers a bit. So you could watch the first five pointers in C videos before doing this problem, if time.

Your program declares an array of ten ints.

It calls a function named "fillarray" to read up to ten ints into that array from stdin using scanf() in a loop. Make this function reasonably general; it should not hard-code the number ten. If there are more than the specified number of ints on the standard input, excess values are ignored.

Write a function named "stats" which takes an array and outputs the min, max, and mean values in that array. You may use integer arithmetic throughout (thus truncating the mean to an integer).

Your main() function, after calling fillarray(), will call stats() on the whole array, then the first half of the array, then the second half of the array, labelling the output appropriately. Note that it is not necessary to copy or subdivide the array in any way. Just pass in (to your stats() function) the appropriate base address of where to find integer values from (using pointer arithmetic), and the number of integers that your stats() function should find starting at that location.

Example run, where '$' is the shell prompt (and remembering that the output of "seq 0 2 10" is 0 2 4 6 8 10):

$ seq 0 2 10 | ./a.out
Full array:
min: 0
max: 10
mean: 5
First half of the array:
min: 0
max: 4
mean: 2
Second half of the array:
min: 6
max: 10
mean: 8
$ 
For further samples, experiment with my solution (compiled, so that you can't see the source code!) in /u/csc209h/summer/pub/lab/04/stats

Call your file "stats.c".
Please use exactly the above fixed strings for easier automated testing.

As usual, your file must compile on the teach.cs machines with "gcc −Wall" with no warning or error messages.


Problem 7: Calculator (not for credit)

Write a simple interactive calculator which operates on individual characters as input. The user will have to press return for your program to react, so make it ignore newline characters (or, optionally, just ignore all characters it doesn't know).
It has a stack of up to ten ints.
If the input character is a digit, that number is pushed on the stack. (You can't type multi-digit numbers.)
'+' pops the top two numbers off the stack and adds them and pushes the result back on the stack.
'p' prints the top of the stack.
'f' prints the entire stack.
'c' clears the stack (i.e. it is now size zero).
Add further operators as desired (popping arguments off the stack and pushing the result).

Output an error message if you attempt to operate on more numbers on the stack than are currently on the stack.

To declare an array of ten integers, write:

	int stack[10];
Then you can access stack[3], or stack[i] for a variable or expression i, etc.

Also recall:

        int c;
        ...
        while ((c = getchar()) != EOF) {
            ...


To submit

First of all, during the lab time, you must run "/u/csc209h/summer/present" on the console of a lab workstation, or get the TA to mark you as present.

Then, by the end of Friday June 3, you must submit your C files for problems 2 and 6. Submit with commands like

	submit -c csc209h -a lab04 rot13.c stats.c
You may still change your file and resubmit any time up to the due time, using "−f" as described towards the end of lab one; and you can use "submit −l" as also described in lab one.