every.c, mywc.c, and shuffle.c). You can drag the entire warmup directory to
Gradescope to do this; it’s fine if you upload Makefile as well, but I will build your program using
my own Makefile.
Many of you haven’t used the C programming language since CSC 161, so there’s a good chance you’ll feel a little rusty. After working with more modern languages like Java or Ruby, it’s easy to forget what it was like to live in the anything-goes, hoist yourself by your bootstraps world of C programming. By modern standards, the functionality built into C and its standard library is minimal and a bit cumbersome. This lack of built-in functionality often means you’ll be implementing your own basic functionality, which gives you an incredible degree of control over what your program does and how it does it. At the risk of perpetuating a cliche, I’ll emphasize that with great power comes great responsibility.
You aren’t completely on your own with C, though. The C language has been closely matched with the POSIX standard library, which provides quite a few handy utilities that are certainly worth using. The purpose of this lab is to help you regain some familiarity with the C programming language and get a sense of what’s available for reuse rather than reimplementation.
To start this lab, download the file warmup.tar.gz archive and extract it.
You can then build each of the three programs you will need to finish by running make.
The following terminal session shows how to do this, in case your terminal skills are a bit rusty.
student@turing:~$ mkdir csc213
student@turing:~$ cd csc213
student@turing:~/csc213$ tar xvzf ~/Downloads/warmup.tar.gz
warmup/Makefile
warmup/every.c
warmup/mywc.c
warmup/shuffle.c
student@turing:~/csc213$ cd warmup
student@turing:~/csc213/warmup$ make
clang -g -Wall -Werror -o shuffle shuffle.c
clang -g -Wall -Werror -o every every.c
clang -g -Wall -Werror -o mywc mywc.c
student@turing:~/csc213/warmup$ ./shuffle
King of spades: K♠
Two of clubs: 2♣
Ace of hearts: A♥
Jack of diamonds: J♦
Note that this output includes the shell prompt (student@turing:~$) and command output, neither of which should by typed into your terminal window.
Just type the command that appears after the dollar sign and hit enter to run the command.
At this point you should move on to part A of the lab.
One important thing to remember about C is that types are more of a suggestion than a rule;
chars are just numbers that, by convention, correspond to specific characters.
There are quite a few nice built-in characters like the following suits of cards: ♥, ♦, ♣, and ♠.
Edit the shuffle.c file so it prints all of the cards in a standard deck (2–10, Jack, Queen, King, and Ace of each suit).
You are welcome to print the cards in any format you like;
one common format is K♥, 2♠, etc.
Hint: Assign a number to each unique card so you can print it easily. You don’t need to use a lookup table here if you can come up with a nice formula to turn a number between 0 and 51 into a specific card.
Once you can print the entire deck, change your program so it will print a shuffled deck.
Make sure your implementation gives a new shuffled order on every run!
Use the rand function to generate random numbers.
Use the command man 3 rand to read about it, or go to this web-based manpage viewer: linux.die.net.
For this part, you will be writing a procedure called every that takes three arguments: the number of times to run a function, the number of milliseconds between calls to that function, and the function itself.
For example, if I call every(10, 500, myfun), there should be ten calls to the function myfun each starting 500ms apart.
The first call should happen immediately, and the tenth should run approximately 9500ms later.
You do not need to account for the time myfun takes to run.
For example, if myfun takes 100ms, you would still wait 500ms between calls (so each call starts at a 600ms interval).
You will likely need to use the nanosleep function for this part of the lab.
If you are looking for an additional challenge, implement a version of every that runs in the background.
You’ll need to use timer_create and signal to do this.
One nice perk of this approach is that you can have multiple “tasks” running with every at any given time.
Use the fgets function to read a string from user input (a file named stdin), and count the number of words in the input.
For simplicity, a “word” is any non-empty sequence of characters bounded by whitespace (space, tab, or line break) or the beginning/end of the input.
Use strtok, strsep, or a similar POSIX function to implement your word counting utility;
solutions that do not use POSIX functions for at least some of the word counting process will not receive full credit!
Once you have it working, you should have your word counting utility print out the number of words using printf.
You can test it with a command line invocation like this one:
student@turing:~/csc213/warmup$ echo "the quick brown fox jumps over the lazy dog" | ./mywc
9
There is no upper limit on the length of the input to your program.
You can use fgets to read in some fixed-size chunk of input, count the words in that chunk, then read more input and continue counting.
Be careful when combining word counts for fragments, as the fragment boundary may fall in the middle of a word.