Part 1 - "Hello, World!"

We're going to start things off nice and simple. I'll recommend you create a
cs241 directory in your CS account and a hw1 directory inside
that.

Now that you've got a place for files, go ahead and re-create the "Hello,
World!" program from class. Try to compile it using gccx.
Remember that this is just a shorthand for

gcc -g -pedantic -std=c99 -Wall -Wextra

So if you are playing along from home, you need to be sure that you get no
compilation errors or warnings from compiling using these options. Feel
free to use clang in place of gcc.

Part 2 - Create a Makefile

Now that you've written a C program, you need to write a Makefile to
help you compile and revise it.

Create a file called Makefile

Create a target called hello that compiles the code from Part
1 into an executable called hello. Don't forget the source code
dependency. Remember that the rules line needs to have a tab
character at the start.

Be sure you have this working. If make keeps telling you
everything is up to date, you can just re-save your source file or
touch it to get make to run again.

touch hello.c

Once this is working, add in a target at the top called all
that depends on hello. Test to see if this works.

Now add in a rule at the bottom called clean with no
dependencies. Have it delete hello but nothello.c.

If you are using emacs or vim, you can invoke make from within
your editor window. Both editors can monitor the output and let you jump
directly to the error reported.

Personalizing hello world

Once you have this working, I'd like you to make a few changes in your
first program.

Add a comment section at the top with your name and a description
of the program

Personalize the message that the program prints out. Add in at
least 5 more printf() commands with the following conditions:

At least one decimal number printed with %d

At least one decimal number printed with %Xd where X is an integer number

At least one floating point number printed with %f

At least one floating point number printed with %X.Yf where both X and Y are integers

At least one floating point number printed with %.Yf where Y is an integer

Kudos if you make it somehow interesting to read (poem, story, etc.).

Part 3 - rot128

Next you will create a program called rot128 that will "encrypt"
files by using a rot-128 encryption algorithm. This algorithm is based on
the classic text encryption scheme rot-13 which shifts each letter 13
positions in the alphabet (i.e., 'a' becomes 'n', 'b' becomes 'o', 'z'
becomes 'm', etc.). Two applications of rot-13 returns you to the original.
(Sadly, this has been used as actual protective encryption in
commercial settings.)

Guvf vf zl irel frperg zrffntr rapbqrq va ebg13!

This is my very secret message encoded in rot13!

Instead of just rotating 13 positions, I want you to rotate by half the
allowed range of a char, that way we can encrypt and decrypt any
file on the system. Normally, a char is 8-bits, but since we can't be sure
of that, you should have the program calculate using the proper constant.
(You will need to #include <limits.h> to use this value.)

(UCHAR_MAX + 1) / 2

Add in lines to the Makefile that compile the target rot128 and
add it into both the dependencies for all and as part of the
files removed by clean (being careful not to delete your source
code file).

When you write your program, you should just add the above value to all
characters you read in, and immediately write them out.
You can use getchar() and putchar()
to handle the input and output.
Be aware that getchar() returns an int and you will need to do your
processing on a char to have things loop around correctly.
(Note that the resulting output won't be comprehensible, see the next section about how to store it.)

Be careful to not write out the EOF signal.

Redirecting files in and out of a program

Your "rot128" program reads in from the user typing and writes out to
the console. You can redirect the input from a file and also
redirect the output to a file. Use the "<" character to
redirect an input file, and the ">" to redirect output as
follows:

./rot128 < inputfile > outputfile

Using diff

There is a tool called diff on Unix systems that will report the
differences between files. You can use this to check to see if your
program is indeed working.

% vi mytext # create a text file
% ./rot128 < mytext > mytext.enc # create an encrypted file
% diff -q mytext mytext.enc # ask to see if they are different
# -q tells it to not show the
# differences
Files mytext and mytext.enc differ
% ./rot128 < mytext.enc > mytext.out # run your program on the DOS text
% diff -q mytext mytext.out # should have no output as they are
# the same

Part 4 - ASCII art

Finally, you'll be creating a program called diamond that
generates a simple ASCII art diamond of variable size based on user input.

getdigit()

First, I want you to create a function called getdigit() that returns
an integer. I.e.,

int getdigit();

with the following properties:

Reads characters using getchar() until either it sees either
a value between '0' and '9' or EOF. You might find the isdigit()
man page enlightening.

If it sees EOF, return -1

If it sees a digit, return the integer corresponding to that.
E.g., '3' should return 3.

Ignore all other values input by the user, only use the first digit
encountered. For example, a user typing "abc123" returns 1, a user typing
"452" returns 4, and so forth

Prompt the user to input an size, and then use that to create a diamond
shape. The size the user inputs is the height of one of the triangles
that make up the shape (the distance from a point to the center).