CS16, Winter 2010

lab03: ("lab three")
atoi, Command Line arguments, ASCII art


Goals for this lab

By the time you have completed this lab, you should be able to:

You'll also get more practice with:

Skills Needed

By now, we expect that you are comfortable with these basic skills from lab00, lab01, lab02, so we will no longer describe them in as much detail as we did previously:

This is a pair programming lab!

Work with your assigned pair programming partner on this lab—the same one as for lab05. If you do not have one, consult the TA for your lab and/or your instructor for advice prior to starting.

Keep the evaluation criteria in mind

As you work with your pair partner, keep in mind that part of your grade will be determined by how he/she answers these questions. So try to be a good partner!

1. Did your partner read the lab assignment and preparatory materials before coming to the scheduled lab?
2. Did your partner do a fair share of the work?
3. Did your partner cooperatively follow the pair programming model
(rotating roles of driver and navigator)?
4. Did your partner make contributions to the completion of the lab assignment?
5. Did your partner cooperate?

What we'll be doing in this lab:
ASCII Art, and command line arguments

There was a time when laser printers either hadn't been invented yet, or were not yet widely available. Thus, the only kind of printer most folks had access to was something called a "line printer", which printed only from left to right, top to bottom, and could only print the kinds of characters you find on a typewriter keyboard.

So, you might find folks making pictures like this one, found at http://chris.com/ascii/

                                 .ze$$e.
              .ed$$$eee..      .$$$$$$$P""
           z$$$$$$$$$$$$$$$$$ee$$$$$$"
        .d$$$$$$$$$$$$$$$$$$$$$$$$$"
      .$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$e..
    .$$****""""***$$$$$$$$$$$$$$$$$$$$$$$$$$$be.
                     ""**$$$$$$$$$$$$$$$$$$$$$$$L
                       z$$$$$$$$$$$$$$$$$$$$$$$$$
                     .$$$$$$$$P**$$$$$$$$$$$$$$$$
                    d$$$$$$$"              4$$$$$
                  z$$$$$$$$$                $$$P"
                 d$$$$$$$$$F                $P"
                 $$$$$$$$$$F 
                  *$$$$$$$$"
                    "***""  Gilo94'

For now, we'll be keeping things much simpler: we are going to do some very simple ASCII art of letters, numbers and symbols, in order to practice with if/else and for loops.

The first few exercises will be very simple, but they get progressively more challenging.

As an example, we will write a C function that

The function will have the following function prototype:

void starL(int width, int height);

The following table shows various calls to this function, along with their output. The rule is that the L should have height at least 2, and width at least 2, otherwise, it should print no output at all.

Function call Output   Function call Output   Function call Output
starL(3,4)
*
*
****
 
  starL(3,5)
*
*
*****
    
  starL(4,3)
*
*
*
***
    
starL(2,2)
*
**
  
  starL(5,2)
*
*
*
*
**
    
  starL(5,5)
*
*
*
*****
    
starL(1,1)
 
  
  starL(1,2)
 
    
  starL(2,2)
 
    
starL(4,1)
 
  
  starL(2,4)
*
*
*
**
    
  starL(4,2)

*
****
    

So, this is a fairly easy function to write. This will do the job:

void starL(int width, int height)
{ int i; // check if parameters are valid
if ((width<2) || (height < 2))
return; // return without printing anything // print height-1 rows of *\n for (i=0; i<height-1; i++)
printf("*\n"); // print width stars, followed by a final \n for (i=0; i<width; i++) printf("*"); printf("\n"); return; // we are finished
}

To test this function though, we might have to write a tedious kind of main (you can find this in the starLDemo.c program which is part of this week's example code.)

int main()
{
  printf("Output of starL(3,4) appears between lines below:\n");
  printf("========================\n");
  starL(3,4);
  printf("========================\n\n");

  printf("Output of starL(4,3) appears between lines below:\n");
  printf("========================\n");
  starL(4,3);
  printf("========================\n");
 

etc...

Of course, we can do better that this—here are two ways that use things we already know how to do:

Those are both reasonable choices. Instead, though, we are going to learn another new skill—the skill of using command line arguments.

We are going to write a main program called starL.c that allows us to put extra stuff on the command line after the name of the program, and access those values inside the program.

That is, when we compile and run the program starL.c, instead of typing this at the Unix prompt:

./starL

... instead, we are going to type something like this:

./starL 4 5


Inside the program, we'll be able to grab the 4 and the 5 and store those values in int variables called width and height. Then, if we want to test with a new values for width and height, it is as simple as running the program again with different values on the command line.

Ok, that's the general game plan—now lets get started.

Step by Step Instructions

Step 0: If you are still unpaired, or if your pair is more than 5 minutes late, or is absent from lab this week, get a new pair assignment from your TA.

Your TA will tell you who are are assigned to—or you may get your assignment by email.

Please be patient—depending on who shows up, there may have to be some slight adjustments to pair assignments.

We will try to avoid the situation where someone in a group of three, but if may be necessary depending on circumstances.

Step 1: If you are with a new partner, complete a new version of Worksheet W00, and make a
new post to the lab02/lab03 pair partner forum on Gauchospace.

(Otherwise, you can move on to step 2).

If you are with a new partner, we'd like to ask you to complete another copy of W00 and turn it in—along with making the forum post that it calls for—for three reasons:

Turn this in to your TA during your assigned lab section—at the top and in your forum post indicate that it is a "new" pairing for lab03.

You only need to turn in one copy per pair.

Step 2: Decide whose account you are going to work in

Remember: don't share passwords. Instead, use scp or email to share files with each other at the end of each work session. (See lab02, step 2 for details of how to use scp.)

How to share your work with each other

Again for emphasis, I will say it:

Sharing passwords is a violation of your account agreement, and can result in suspension of your computing privileges at UCSB.

Instead, what you should do is:

 

 

Step 3: Log on to CSIL, bring up a terminal window, and create a ~/cs16/lab03 directory.

If you've forgotten how, consult steps 1 and 2 from lab01.

Step 4: Copying some programs from my directory

Visit the following web link—you may want to use "right click" (or "control-click" on Mac) to bring up a window where you can open this in a new window or tab:

You should see a listing of several C programs. We are going to copy those into your ~/cs16/lab03 directory all at once with the following command:

cp ~pconrad/public_html/cs16/10W/labs/lab03/files/* ~/cs16/lab03

The * symbol in this command is a "wildcard"—it means that we want all of the files from the source directory copy be copied into the destination directory namely ~/cs16/lab03.

After doing this command, if you cd into ~/cs16/lab03 and use the ls command, you should see several files in your ~/cs16/lab03 directory—the same ones that you see if you visit the link http://www.cs.ucsb.edu/~pconrad/cs16/10W/labs/lab03/files

If so, you are ready to move on to the next step.

 

Step 5: Experimenting with atoi() in Ch

We won't be working with the C files we copied until a later step in the lab.

First, we are going to use the Ch program to experiment with a function that is part of the standard library, stdlib.h.

This function is called atoi(), and we'll need it for a later step in this week's lab.

In a regular C program, if you want to use these functions, you need to use

#include <stdlib.h>

to pull in the definitions of these functions. In Ch, though, we can just type in some sample function calls and see what happens.

Step 5a: Bringing up Ch

When logged in at a terminal session in the Cooper lab or on CSIL, type ch at the Unix prompt.

You should see something like this (except the directory will be different)

-bash-3.2$ ch
Ch Professional edition, version 6.1.0.13751 (C) Copyright 2001-2009 SoftIntegration, Inc. http://www.softintegration.com /cs/faculty/pconrad/cs16/lab03>
The very long prompt is an indication of what directory you are in. In lab02, we just used cd to go back to our home directory, shortening the prompt:
/cs/faculty/pconrad/cs16/lab03> cd
/cs/faculty/pconrad>

But there is an even better way, which we'll discuss next:

Step 5b: Customizing the Ch prompt

While in Ch, type the following command: _prompt = "Ch> "

This will change your prompt to Ch>

Note the following important details:

Here's what doing that may look like:

/cs/faculty/pconrad> _prompt = "Ch> "
Ch>

Now, your prompt is Ch> (with a space after it).

Step 5c: Experimenting with atoi()

The atoi function converts from a string such as "3" into an int value like 3. We can see how this works at the Ch prompt:

Ch> atoi("3")
3
Ch> atoi("5")
5
Ch> atoi("-42")
-42
Ch>

Note that the argument to atoi must be a string—something in "" such as "3" or "-42". If we use a single character, in single quotes such as '3', we will get an error:

Ch> atoi('4')
WARNING: found char where pointer to char is expected
Ch> 

The error message is saying the atoi found a char ('4') but what it expected was a "pointer to char" such as "4". Here's what "pointer to char" means in this context:

Here's another thing we cannot do with atoi()—we can't pass in an int or a double. Try both of these and see what you get:

atoi(4)
atoi(4.5)

Read the error messages and see if they make sense to you.

Here's a couple of other things to try. These will not result in error messages—instead, you'll get to see what atoi() does when the argument is a string, but does not contain an int—at least not an int all by itself:

atoi("six")
atoi("Go Gauchos")
atoi("4ever")
atoi("d4")
atoi("3.14")
atoi("7.99")
atoi("      5")

Based on what you see here, see if you can discover answers to the following questions. Type in more examples if you need to, in order to find the general rules:

In case you are wondering, the name atoi() comes from "ASCII to integer". ASCII is the code that is used to convert individual characters are converted into binary and stored in the computers memory. In this code, the digit 0 is represented as 48, 1 as 49, 2 as 50, etc.

So, this function converts, for example,

 

Once you are satisfied that you understand how atoi works, you are ready for some programming. Use the exit command get out of Ch and return to the regular Unix prompt.

Ch> exit
-bash-3.2$

Step 6: Working with command line arguments

So far, if we wanted to get input into a program, we could only do it by using scanf.

This week, we'll see another way of getting input into a program: using command line arguments.

As an example, consider two programs that you'll find among the files you copied into your lab03 directory:

The first of these two files, computeAreaOfSquare.c is a traditional interactive program of the type you've seen before.

Now, contrast that with areaOfSquare.c. Look at this one with your pair partner. Notice:

  1. The difference on the first line of the main:
    int main(int argc, char *argv[]) instead of int main()
    • argc is a variable that indicates the number of things on the command line, and argv is an array (or "vector") of the those things.
    • For example, if we type ./areaOfSquare 4, that is two things on the command line
      • ./areaOfSquare is the first thing, and will appear in argv[0]
      • 4 is the second thing and will appear in argv[1]
    • This has been, or will be, discussed further in lecture

  2. The check of argc to make sure it is 2, and the error message that prints if it isn't.
    • If argc is not exactly 2, then we don't have the right number of things on the command line.
    • Either there are too many, which means the user is confused, or there are two few, and if we try to convert argv[1], there won't be anything there to convert.
    • So if argc isn't 2, we print an error message.
    • The standard error message for Unix progams is called a "Usage" message, and it shows the correct usage of the program—i.e. an example of what the command line arguments should be.
  3. The conversion of argv[1] using atoi(), so that it can be stored in the int variable side

Now, compile the program in the usual way ( make areaOfSquare ) and then run it, but when you run it, try these various ways of running it. Based on your understanding of the code you read, and how argc and atoi work, can you explain what happens in each case?

./areaOfSquare
./areaOfSquare 4
./areaOfSquare 6
./areaOfSquare 4 6
./areaOfSquare two
./areaOfSquare 4ever
./areaOfSquare 4.9

 

As you can see one nice thing about command line arguments is that we can test our program with a lot of different values very efficiently.

Optional: If you'd like to see another example of a program that uses interactive input vs. command line arguments, you may also look at the following files, which should also be in your lab03 directory:

Once you've experimented with computeAreaOfSquare.c and areaOfSquare.c and feel you understand how they work, you can move on to step 7.

Step 7: Practicing with the starL program

Now, look at the starL.c program that you have in this week's directory. You'll see that it has the same kind of first line in the main that areaOfSquare.c did:

int main(int argc, char *argv[])

and it has an extra #include, which is needed for the atoi function:

#include <stdlib.h>

This allows us to make the kinds of ASCII Art L's constructed with stars that are shown in the introduction to this week's lab.

Try compiling starL.c, and then run it with various command lines:

./starL 3 4
./starL 4 3
./starL
./starL 2 1
./starL foo bar fum
./starL foo bar

Try to understand what is happening in each case.

When you understand this, move on to step 8.

Step 8: Writing the starT program.

Your job now is to start with the starL.c program as an example, and write a new program called starT.c

It should do roughtly what the starL program does, but instead of having a function starL to make making L's with stars, it will have a function starT that makes the letter T according to these rules:

Here is sample output:

Function call Output   Function call Output   Function call Output
starT(3,4)

(See note* below)
***
 *
 *
 *  
  starT(3,5)
***
 *
 *
 *
 *   
  starT(5,3)
*****
  *
  *
    
starT(3,2)
***
 *
  
  starT(5,2)
*****
  *
    
  starT(5,4)
*****
* * *
starT(5,1)
 
  
  starT(6,5)
 
    
  starT(7,3)
*******
   *
   *
    

*Note: The output for starT(3,4) was blank in the original version of this lab—this was a typo. The correct output is now shown—but if any submissions have special case code so that starT(3,4) would produce blank output, those submissions should get full credit. (P. Conrad, 1/28/2010)

Another hint: you may find the logic of your printKSpacesNXs() function from your homework assignment H06 to be useful here for printing the "stem" of the T.

Test your program by running it on all of the values shown in this table, plus at least two others of your own choosing.

e.g.

./starT 3 4
./starT 3 5
./starT 5 3
./starT 3 2
./starT 5 2
./starT 5 4
./starT 5 1
./starT 6 5
./starT 7 3
... and then two more of your own choosing.

Also test it on cases where you don't have exactly two command line arguments. In those cases, there should be code in the main program (not the function starT) that prints the following message, and returns 1 (instead of 0):

Usage: ./starT width height

When your starT.c program can do all of that, you are ready to script this week's lab:

Step 8a (optional, but helpful testing step---added 11am 01/22/10)

I sent out the following email just before 11am on Friday 01/22/10, the day after this lab was distributed.

Dear CS16 students:

I'm working on an automated test script for lab03 that will help you find errors in your program _before_ you submit it for grading.

I am not 100% sure that the test script itself is bug free, but it seems to be working pretty well at the moment, so I think it is ready for you to try it out.

To use the test script:

  1. cd into your ~/cs16/lab03 directory

  2. run the following unix command:

    ~pconrad/public_html/cs16/10W/labs/lab03/test.sh

  3. The output you are hoping for is something like this:

     -bash-3.2$ ~pconrad/public_html/cs16/10W/labs/lab03/test.sh
      make: `starT' is up to date.
      Test passed for ./starT
      Test passed for ./starT 3 4
      Test passed for ./starT 3 5
      Test passed for ./starT 5 3
      Test passed for ./starT 3 2
      Test passed for ./starT 5 2
      Test passed for ./starT 5 4
      Test passed for ./starT 5 1
      Test passed for ./starT 6 5
      Test passed for ./starT 7 3
      -bash-3.2$

    If so, you are in good shape.

  4. The output you might see instead is something like this:

    Test FAILED: for ./starT
    =============expected output==========
    Usage: ./starT width height
    ==============actual output===========
    Usage: ./starL width height
    ======================================
    

    which shows that you forgot to change your "usage" message (starL vs starT)

    Or:

    Test FAILED: for ./starT 3 4
    =============expected output==========
    ***
     *
     *
     *
    ==============actual output===========
    ***
     *
     *
     *
     *
    ======================================
    

    which shows that you didn't quite count the height of the vertical bar correctly (remember that the top row already contributes one star to the height.)

    Finally, if you get an error like this one:

     /cs/faculty/pconrad/public_html/cs16/10W/labs/lab03/tests/checkit.sh: line 20: 25243 Segmentation fault (core dumped) $@

    It probably means that you are trying to do something like:

     width = atoi(argv[1]);
    before you check the value of argc, which is a no-no.

    Always check argc first to make sure that argv[1], argv[2], etc actually exist before doing anything with the argv[1], argv[2], etc. values.

    Otherwise, you may get the infamous "segmentation fault" error that occurs when you try to access a piece of memory that isn't really there, or that you aren't allowed to see...

  5. If you find errors, and you already submitted, no worries---just fix the errors, and submit again, as long as it is before the deadline of next Friday. The "turnin" program is configured to allow up to 5 submissions per lab at the moment.

  6. If you find any problems with the testing script itself, please let me know.

Happy testing!

Step 9: Scripting your assignment

Before doing the transcript—look over the grading rubric at the bottom of this page. Make sure you've done everything properly to maximize your grade.

In this step, we create a "transcript" of your work. We only do this after everything else is finished, and you are sure you have a good working product.

Now, to create your script:

  1. Use the proper form of the cd command to put yourself in your ~/cs16/lab03 directory (if you aren't already there)
  2. Type script lab03.txt
    You'll get back a regular looking unix prompt, but something is different now—everything you type, and everything that comes back from the computer is being recorded into a file called lab03.txt. It's like turning on the video camera.
  3. Type pwd to show what directory you are in.
  4. Type ls to show what files you have.
  5. Carefully—type rm starT to remove the starT excutable.
    • We do this so that when you type "make starT" in a later step, we'll see your program compining instead of the message "make: `starT' is up to date."
    • Don't accidentally remove the starT.c file or you'll be starting over from scratch!)
  6. Now, type make starT to compile your program. There should be no warnings and no errors.
  7. Next, run through all the commands listed in Step 8 to show that your program works properly, e.g.

    ./starT 3 4
    ./starT 3 5
    ./starT 5 3
    etc.

    Don't forget to include the commands that show that it works when you don't have the right number of command line parameters.

  8. Type exit to stop the recording of commands and responses into lab03.txt

When finished, type ls one more time, and you should see a new file in your lab03 directory called lab03.txt.

Use this command to list out the contents of that file:

cat lab03.txt

You should see your life flashing before your eyes, so to speak—a feeling of déjà vu should come over you—because everything in the file will be what you just typed and what came back over the last few minutes.

If so, you are ready to submit!

Step 9. Submit your assignment using the turnin program on CSIL

To submit your assignment, you need to be in the ~/cs16 directory—one level higher than the previous step (use cd ..)

When you are in inside your cs16 directory, you are ready for the turnin step.

Type the following at the prompt:

turnin lab03@cs16a lab03

If you need detailed information about how turnin works, consult the instructions in lab00 through lab02.


Evaluation and Grading (200 pts total)

Due Date: You should try to complete this assignment by the end of the discussion section in which it was assigned.

If you are unable to complete it by the end of your discussion section you may continue to work on it through the week—ideally before the start of next week's discussion section.

It will be accepted without late penalty until 5pm on Friday January 29.

Late assignments will only be accepted (with 20 point penalty) through 5PM on Wednesday Feb 3rd

After 5PM Wednesday Feb 3rd, a zero will be recorded, and the only option is to make up the points via extra credit.


Copyright 2009, Phillip T. Conrad, CS Dept, UC Santa Barbara. Permission to copy for non-commercial, non-profit, educational purposes granted, provided appropriate credit is given; all other rights reserved.