Lab 3: Structs

The goal of this lab is to learn basic C structs.

1. Introduction

You are writing software for a Twitter knock-off called Chatter. In the Chatter system, users send messages whose text is at most 140 characters long. Additionally, each message has the user id of the user who sent the message (at most 16 characters long), a time stamp indicating the time the message was sent (a long int indicating the number of milliseconds since midnight, Jan 1, 1970), and up to 5 hash tags indicating categories or topics the message falls under (each hash tag is at most 10 characters long).

I have provided some code for producing "random" text components and "random" user names. Your tasks will include designing and implementing a struct to represent messages, writing functions for displaying and sorting messages, and completing drivers to test these messages.

2. Set up

Set up a new directory for this lab and move into it.

mkdir lab3
cd lab3

Copy starter code from the course directory.

cp /homes/tvandrun/Public/cs245/lab3/* .

This will give you the following files:

3. Given code

The chatter_util library provides the following functions:

4. Tasks

You need to complete the following tasks:

A. Design and implement the struct

The first thing is to design and implement a struct to represent chatter messages. This is kind of like writing a class in Java, but simpler. I have already set up a dummy struct for a message type in message.h.

Write the message struct. Think about the components to a message and how one would store that information. Recall from the in-class examples that you can declare static arrays inside a struct type.

Since you haven't written any functions yet, there isn't much to test. However, you can make sure you didn't make any syntax errors by compiling something that uses the message type. The test case test_message_def will also catch a few possible mistakes. Make and run this test case:

make test_message_def
./test_message_def

If you get Test passes, then you're still not guaranteed you have the struct exactly right, but you can move on. If you get an error message, then first figure out what's wrong.

B. Make a new random message

Now we need to produce a new message, that is, a value of our new message type.

The header file message.h gives the prototype for the function newRandomMessage() which is used by the two driver programs. Write a definition for this function in the implementation file message.c for the message library.

Use the functions from chatter_util to produce the text, user name, and hash tags:

You can test this using test_new_message. Of course, in all this you may discover problems with how you made the struct in the previous step.

make test_new_message
./test_new_message

C. Display a message

The headerfile message.h gives the prototype for the function display() which displays a message to the screen, nicely formatted, showing all the information stored about that message. The display of a message should look something like this:

-----------------------
Sent by Verna at 1315499047608
Q: How can you tell if an elephant is in the refrigerator?
A: The door won't shut.
#mischief
#concert
#admiration
#concert

If you want the date to appear as something nice looking instead of a number of milliseconds, instructions for that are found in the optional section at the end of this lab description..

Write the implementation of display() in your message.c.

Test this using test_display

make test_display
./test_display

This will not report whether there was an error or not, it will simply show you the results. You need to inspect them to make sure they are right. (Of course there could be an error from having your program crash.) There are three tests- displaying one message, displaying three messages, and displaying an array of 10 messages. This will be a fair amount of output. You'll have to scroll up to see it all, or you could send the output to a file. To send the output of this program to a file called results, do this:

./test_display > results

You then can open results in the text editor, which might make it easier to read.

Remember, this is testing everything you've done so far, so if it's not right, you may need to go back to an earlier step.

D. Count the messages for a user

Our next task is to write a function that will take an array of messages and the name of a user of the system and count how many of the given messages were sent by the indicated user. Essentially you will need to loop over the array, checking the userid of each message and seeing if it matches the userid given as a parameter, counting the number of matches.

To compare strings in C, use the function strcmp(). This takes two strings (that is, character arrays) and returns 0 if they are equal. (This function can also be used to put strings in alphabetical order; it will return a negative number if the first string comes first alphabetically and a positive number if the second string comes first.)

Write the function countForUser(). Test it using the program test_count_user:

make test_count_user
./test_count_user > results

This program will display 50 messages and then indicate how many occurrences of a chosen userid there are. Notice that I'm suggesting sending the output to a file named results (which will overwrite any older file of the same name---you can name it something else if you want.). Verify that your function works by counting the number of messages sent by that user and seeing if it matches the results returned by your function. (You can search for a string in emacs or xemacs using ctrl-s ("s" for "search) or in gedit using ctrl-f ("f" for "find").)

Test and verify several times.

E. Filter messages by hash tag

The final task is to take an array of messages and search for ones that have a given hashtag. The function filterByHashTag(). This function is given two arrays: one contains a sequence of chatter messages (original), and the other can be regarded as "blank" (filtered). It also takes parameters indicating the number of messages in the array and a hashtag. This function should iterate over the array of messages and check each message to see if it has the hashtag. If it does, that message is copied into filtered. The function also returns the number of messages that have the hashtag (and thus have been copied into filtered).

One thing that makes this task harder than the previous is that a message may have up to five hashtags. For each message, we need to see how many hashtags the message has and check each one against the given hashtag (again using strcmp()).

Write the function filterByHashTag(). Test it using test_hashtag_filter:

make test_hashtag_filter
./test_hashtag_filter > results

This test program will print the original list, the hash tag it's looking for, and the filtered list returned by your function. Check the results to make sure that all (and only) the messages that contain that hashtag are found in the filtered list.

5. Pretty displaying of the time (optional)

If you want to make a readable formatting of the time stamp, do the following things to your code:

Then the display of a message would look something like

-----------------------
Sent by Willis at Thu Sep  8 12:32:37 2011

Q: Why do elephants stomp on people?
A: They like the squishy feeling between their toes.
#surplus
#moisture

Thomas VanDrunen
Last modified: Mon Aug 3 10:41:45 CDT 2015