Part 1: Code editors and SFTP
If you haven’t done so already, follow along with this guide on IDEs vs. code editors and getting an SFTP client set up on your computer.
Part 2: sizeof()
is not how you get the length of an array
Note: what you learn in this part is important and I’ll expect you to know it in future labs, projects, and on the exam. So you need to do it, even if there’s nothing to turn in.
Let’s do an exploration about the sizes of variables in C. Head over to this exercise and do it.
Part 3: Text I/O
-
In your
private/cs0449/labs
directory, you want to make a new file for this lab. You can do it with this command:touch abc123_lab2.c
(But with your username instead of
abc123
. You get it by now I hope.) This will create an empty file namedabc123_lab2.c
. - If you already have your
labs
directory open in your SFTP client, it will not immediately appear. You will have to refresh it (Ctrl+R or ⌘R) to get the updated list of files. - Then you can edit your lab however you like - through
ssh
or through your SFTP client.
Here are some helper functions. Feel free to reuse these functions in future labs/projects.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
void get_line(char* buffer, int size) {
fgets(buffer, size, stdin);
int len = strlen(buffer);
// this is a little more robust than what we saw in class.
if(len != 0 && buffer[len - 1] == '\n')
buffer[len - 1] = '\0';
}
// returns 1 if the two strings are equal ignoring case, and 0 otherwise.
// so "earth" and "Earth" and "EARTH" will all be equal.
int streq_nocase(const char* a, const char* b) {
// hohoho aren't I clever
for(; *a && *b; a++, b++) if(tolower(*a) != tolower(*b)) return 0;
return *a == 0 && *b == 0;
}
What your program will do
This program will calculate how much the user weighs on various planets in our solar system. This is some CS0007 stuff for sure, but many of the steps are quite different from how you’d do them in Java. Here’s how your program will work:
- Ask them how much they weigh. (This is unitless because we’re working with ratios.)
- Ask them what planet they want to visit.
- If they typed
exit
, usebreak;
to exit the loop (and therefore end the program). - If they typed
earth
, sayYou're already there!
- Otherwise,
- Get the scaled weight for that planet using your
planet_to_weight
function (see below). - If it returned a value less than 0, that means it’s not a planet, so say
That's not a planet.
. - Otherwise, tell them how much they’d weigh there in this format:
"You'd weigh %.2f there.\n"
- Get the scaled weight for that planet using your
- Go back to step 2.
Here’s how it looks when I interact with my program:
[cs0449vm ~/private/cs0449/lab2]: ./lab2
How much do you weigh? 250
What planet do you want to go to? mars
You'd weigh 95.00 there.
What planet do you want to go to? JUPITER
You'd weigh 635.00 there.
What planet do you want to go to? pluto
That's not a planet.
What planet do you want to go to? earth
You're already there!
What planet do you want to go to? exit
[cs0449vm ~/private/cs0449/lab2]:
It’s important that your program’s output matches mine, because the autograder will be somewhat picky about the output. If you add extra prompts, messages, blank lines, format the output differently etc. you may confuse the autograder and then have to spend a bunch of time just making it happy. So, don’t get crazy with the output. Just make your program work the same way as this example above.
Reading a number
First we’ll read a number, the user’s weight (sorry if that’s sensitive info… you can just type in Some Number if that makes you uncomfortable).
-
Use the
get_line
function from above to ask the user for their weight.printf("How much do you weigh? "); char input[100]; get_line(input, sizeof(input)); // notice the sizeof!
We used
sizeof(input)
so we don’t have to repeat the 100. Also, that avoids mistakes if you change the size of theinput
array.I know, I said
sizeof()
doesn’t get the length of an array. But forchar
array variables - and ONLY forchar
array variables - it technically does. It’s a very limited tool, but it’s a tool nonetheless. -
Use
sscanf
to parse the number out of the string. You use it like this:int weight; sscanf(input, "%d", &weight); // DON'T FORGET THE & or it'll crash.
sscanf
meansstring scan formatted
. It’s likeprintf
backwards. It can parse values out of a string.How this works is by handing off a pointer to the
weight
variable tosscanf
. The"%d"
argument tellssscanf
to look in theinput
string for an integer.sscanf
converts it from text to a binary value, and it puts that value into theweight
variable directly. (Or, indirectly? Through the pointer? Whatever.) -
Compile and run it to see if it works. Never write a whole program at once. Compile early, compile often.
Compile like
gcc -Wall -Werror --std=c99 -o lab2 abc123_lab2.c
. (This is a long line, but remember that at a command line, you can use the up and down arrows on your keyboard to find previously-entered commands to run them again. So you only have to type it once, and then you can reuse it infinitely.Then run like
./lab2
. (You can print out theweight
variable after thesscanf
to see if it was parsed correctly, but remove that print after you’ve tested and confirmed it.)
Making a function
The const
means “I only want to read the string from this variable, I promise I won’t change it.” We’ll talk about it later in the term.
Before main
, make a function with this signature:
float weight_on_planet(const char* planet_name, int user_weight)
This function takes the name of a planet and a weight, and returns:
- what you’d weigh on
planet_name
by multiplyinguser_weight
by that planet’s gravity (see below), or - -1 if
planet_name
is not a planet.
Here is a table of relative gravity strengths on the seven non-earth planets in our solar system:
Planet | Gravity |
---|---|
Mercury | 0.38 |
Venus | 0.91 |
Mars | 0.38 |
Jupiter | 2.54 |
Saturn | 1.08 |
Uranus | 0.91 |
Neptune | 1.19 |
You can’t switch
on a string in C like you can in Java. Instead, you will use streq_nocase
to check which planet it is, e.g.
if(streq_nocase(planet_name, "mercury")) {
// it's mercury.
} else if // etc
The “case-insensitivity” of streq_nocase
means they can type e.g. “mercury”, “Mercury”, “MERCURY” and it’ll all work the same way.
Now test that the function works before you make the loop. Call it from main
with a few values and print out what it returns. See if it behaves how you expect. Test, test, test. Testing your own code BEFORE you use it will save you so much trouble.
Loopydoop
Finally you need to add the loop to main
that does steps 2 to 5 in the program description from before. true
is not a thing in C by default, so you have to #include <stdbool.h>
at the top if you want to use it. Then you can write while(true)
like you’re used to. Alternatively, you can write while(1)
. Because 1 is true! Sure!
In that loop, you’ll be:
- reading a line of input from the user
- using
streq_nocase
to see what they typed in.- Remember that you have to check for
"exit"
and"earth"
specifically. - Then, if it’s neither of those, use
weight_on_planet
and print out the appropriate thing. Go look at the program description above!
- Remember that you have to check for
Submission
We will be compiling your program with these compiler options, so make sure your program compiles with them:
gcc -Wall -Werror --std=c99 -o lab2 abc123_lab2.c
Also, this time, the autograder/submission will not be open immediately. This is so that you learn to do your own testing. I will open up the autograder a few days after the lab is released and announce when I do. This is how it will work from now on.
Once you’re ready to submit and the autograder is online, you can use your SFTP client to copy your _lab2.c
file to your computer. Figure out how to do that in your SFTP client! It’s not hard!
Then just like for lab 1:
- Go to the canvas for this course.
- Click Gradescope on the left.
- Click on Lab 2.
- Drag your
_lab2.c
file into the Gradescope submission thingy. - Wait for the autograder to complete!
If the autograder says something is wrong with your submission, fix it, re-download it to your host computer, and re-submit it as many times as needed to fix the problem.
Note that future assignments may have a limited number (or rate) of resubmissions, so do not rely on the autograder to be your only method of finding and fixing problems!