CSCI 241 - Homework 2 - Introduction to C
Due by 11:59.59pm Tuesday, February 21
For this assignment you will be:
- Creating several small C programs
- Writing your own Makefile
- Learning about shell redirection
- Learning to use diff to compare outputs
- Learning how to use github for submission
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 hw3 directory inside that.
First off, go to https://classroom.github.com/a/9IZR3LGY and create a repository in the CS 241 organization.
Click on the link and head towards the created repository. It will be called hw02-username
I put some starter files in hw2.zip. Feel free to use them or not, but your files should be named the same as they are in that .zip file. There’s also a grader.sh script there. More on that later.
Go back to your CS account to the cs241 directory above, and clone the repository into this account. Refer to the github tutorials for how to do this step.
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 not hello.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
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).
Sample output
% ./diamond I will print a diamond for you, enter a size between 1-9: abc123 * % ./diamond I will print a diamond for you, enter a size between 1-9: 568 * *** ***** ******* ********* ******* ***** *** * %
Part 5 - README
Finally, I want you to create a file called README (note all caps and no file extension) which contains the following sections:
- Your name and the date
- A list of the programs with a short one-line description of each
- A list of all compilation problems, warnings, or errors. Note that for full marks, it is expected that you will have corrected all of these things.
- How long it took you to complete each part.
- The honor code statement:
I have adhered to the Honor Code in this assignment
You may also want to run the grader.sh script at this point. It is similar to what we will use to grade your submission. It is highly recommended that the script run without major issues before you submit.
Part 6 - Submission
Now you should make clean to get rid of your executables and handin your folder containing 4 files (don’t worry if your *.c files have different names as long as the output is the same):
- Makefile
- hello.c
- rot128.c
- diamond.c
- README
Run git commit to push your changes. You should check via the github web interface to make sure that your files have been submitted properly.
Extra Credit
- Read in a number from the command line for rot128 and use that as the base for rotation.
- Make the diamond inverted if the user types in a negative number. So, instead of writing a '*' inside the diamond, write it outside the diamond and a ' ' inside.
Grading
Here is what I am looking for in this assignment:
- A working Makefile with your programs, all, and clean as targets
- A working hello.c with requisite output
- A working rot128.c
- A working diamond.c
- All programs should have comments including your name and date at the top. Functions should have a brief description of what they do and an explanation of their return values.
- All programs should compile using gccx on OCCS or Clyde with no compiler warnings or errors.
Last Modified: Sept. 20, 2022 - Roberto Hoyle, based on material from Benjamin Kuperman