ENGG 335: Computing for Engineers II

Lab 1 Spring 2004

 

Last modified and updated in May 2004

Introduction

The purpose of this assignment is to gain some basic skills needed to use the Common Core Linux workstations in ENGG 335.

Preparation

Please read this handout carefully before coming to the lab.

Ask for help if you get stuck!

It is essential that you learn the basic skills required to do assignments in this course. Additional skills will be added with each Lab. If you fall behind early in the course it will be hard to catch up later.

You will likely get stuck a few times. When you get stuck, please ask for help from lab instructors or graduate teaching assistants. Don't be embarrassed about asking `stupid' questions--everybody has lots of these when learning to use a computer system.

Where to go

The lab will start every at 8:00am. 

Due Dates:

Wednesday May 26, at 2:00 PM.   

Important Note: you should write your name and your lab section number on every assignment you hand in and type it into every file of source code you write.  Marks will be deducted if any of this information is missing.

There will be no credit for assignments turned in after the Late Due Date; they will be returned unmarked.

Assignments must be dropped in the assignment boxes located on the 2nd floor of the ICT building, before 1:30 PM on due dates indicated above. 

The following rules apply to this lab and all other lab assignments in future:

  1. In order to make it as easy as possible for teaching assistants to manage their large piles of assignments, please make a cover page for your assignment out of an ordinary piece of paper. Handprint `ENGG 335 Lab 1', your name and lab section number on the cover page in large, easy-to-read lettering. The cover page should look like something this:
      ENGG 335 
      Lab 1
      Lab Instructor: xxxxx  
      Student Name:  xxxxx
      Lab Section: for example, B19
      Date submitted: for example,  May 26, 2004 
      

Do Not Put Your ID Number on the Cover Page. One mark will be deducted for not having a proper cover page.

  1. Take a moment to make sure that you are handing in all the material that is required. If you forget to hand something in, that is your fault; you can't use `I forgot' as an excuse to hand in parts of the assignment late.
  2. As a favor to your teaching assistants, check carefully that you have ordered the pages correctly.
  3. STAPLE the pages together securely. Assignments held together with paper clips will fall apart in the collection boxes. Markers are not responsible for finding missing pages.
  4. Your name, student number, and lab section number should also appear in a C++ comment at the top of each source file you write
  5. Assignments must be dropped in the assignment boxes located on the second floor A block, in the engineering building.
  6. Make sure to drop your assignment in the box labeled with your lab section; the course staff are NOT responsible for finding assignments placed in the wrong box.

What to hand in / Marking scheme:

 

Ex B: printout of file silly_song (1 mark)

Ex F: printout of your program (4 marks)

Ex G: printouts of program and table  (2 mark)

 

Don't hand in anything for Exercises A, C, D, and E.

 

Total marks available: 10

Exercise A: Introduction to the file system

To do lab exercises in this course you must learn the basics of working with files and directories in Unix-like file systems. In Unix, / [``slash''] is the directory separator character.  The following figure shows a simplified view of an ENGG Linux workstation file system:

 

Whenever you log in to a Linux workstation, you start off in your home directory. Your home directory is located in /nsf/home. The name of your home directory is the same as your login name. So if your login name is msmith, your home directory would be  /nsf/home/msmith.

Every Unix directory has two special entries:

  1. . (``dot'')
    This is shorthand for the directory itself.
  2. .. (``dot dot'')
    This is shorthand for the directory one level up.

``Dot'' and ``dot dot'' are both used frequently in Unix commands.

 

Some Unix commands:

  1. pwd
    print working directory--use this to find out where you are in the file system
  2. cd directory
    make
    directory become the working directory
  3. cd
    make your home directory become the working directory
  4. ls
    list contents of the working directory
  5. ls -l (letter l, not number 1)
    list contents of the working directory, giving size, date and other information
  6. ls -a
    list contents of the working directory, including files and directories whose names start with a ``dot''
  7. more text_file
    show contents of
    text_file one screenfull at a time
  8. cat text_file
    also show contents of
    text_file one screenfull at a time

What to do

 

Right-click on blue background of your screen, and select New Terminal  to launch a Terminal window, then complete the steps listed below by typing commands into the Terminal window.

(1) What is your home directory? To find out, use the pwd command.

(2) Get into the root director (/). Do this with ht following command:

cd  /

(3) Get into the directory engg33. Do this with the following sequence of commands:

cd nfs

pwd

cd home

pwd

cd engg335
pwd

(4) Get back to your home directory. Do this with the following sequence of commands:

 

cd ..

pwd

cd your_user_name (for example: cd msmith)

  

What are the outputs of the pwd commands? (Note: Normally there is no need to move up and down one level at a time--the point of this exercise is to get you used to the idea of levels in the file system.)

(5) What files and directories are in the /nfs/home/engg335/lab1/exC directory? To find out, use the ls command.

(6)  What are the sizes of the files in the directory exC? You can find this out with the ls -l command. In the output of this command, the size of a file in bytes is given just to the left of the date of last modification.

 (7) What are the first six lines of the file /nsf/home/engg335/lab1/silly_song? To find out, first make sure you are in /nfs/home/engg335/lab1, then type the command

more silly_song

 (8) Go back to your home directory by entering cd without specifying any directory on the command line. Use pwd to check that cd worked.

(9) Use ls to list the files and directories in your home directory. What output is produced? Now try the command

ls -a

What is the output? (More files and directories should be listed this time, including several files and directories whose names start with a dot.) Files whose names start with a dot usually contain key customization data for your account and for programs you use. Don't try to edit or delete them unless you are sure you know what you are doing!

 

Exercise B: Making a directory, copying a file, editing text

Read This First

The Unix command for copying files is cp. When you use cp to copy a file from one directory to another, you must always specify the directory into which the file is to be copied. In this respect, cp does not work the same way as the MS-DOS COPY command.

Unix commands important for this exercise:

  1. mkdir dirname

create directory with name dirname in the working directory

  1. cp filename dirname

copy file filename into directory dirname

  1. emacs

start GNU Emacs `in the foreground'--necessary if you are not using the X Window System

  1. lpr textfile print textfile on line printer

Some essential Emacs jargon:

Buffers are not the same as files, but they are related. To edit a file, you load the file into a buffer, change the buffer, then save the buffer as a file. Changing a buffer does not immediately change the corresponding file. To change the file, you must save the buffer.

Point is a location in between two characters in a buffer. So is the mark. Point is always immediately in front of the cursor. So if the cursor were sitting on the g in the word program, point would be the location in between the o and the g. Various user commands set the mark. Often you set the mark to be the same location as point by typing C-SPC (holding down the Ctrl key and pressing the space bar), then you move point (by moving the cursor) to create a region.

The region is the text in between point and mark. There are many, many commands that can be applied to the region. The most common operation on the region is killing it, either to get rid of it, or to prepare it for yanking somewhere else in the buffer.

`Kill' and `yank' are the Emacs words for `cut' and `paste'.

Important Emacs commands:

C-a       move to beginning of line 
C-e       move to end of line
 
C-d       delete character covered by cursor
Delete  delete character to left of cursor 
C-k       kill text from cursor to end of line
 
C-SPC     set mark (SPC stands for space bar)
C-w       kill region
C-y       yank most recent kill back into buffer
 
C-x C-f   load file into Emacs, or open a new file
(you will be prompted to type in a file name)
 
C-x b     switch to another buffer
(you will be prompted for the name of the buffer to switch to)
 
C-x C-s   save buffer, using existing file name
 
C-x s     save many buffers, using existing file names
 
C-x C-w   save buffer, but with a new file name
(you will be prompted to type in a file name)
 
C-x C-c   exit Emacs

Note that in Emacs documentation C-a means `control-a', which is typed by holding down the Control key and pressing the `a' key. (C-b means `control-b', and so on.)

A few more useful Emacs commands are listed on the One-Page Emacs Guide for ENGG 335.

What to do

First, make sure you are in your home directory. (Use pwd.) Then make a directory called lab1 with the command

mkdir lab1

Use ls to check that your lab1 directory was created. Then use cd to get into this new directory.

Copy the file silly_song from /nfs/home/engg335/lab1 into your own lab1 directory with the command

cp /nfs/home/engg335/lab1/silly_song  .

Note: the `dot' at the end of the command line is an essential part of the command! It tells cp that the file is to be copied into the working directory.

Start the GNU Emacs editor with the command

emacs

Load the file silly_song into Emacs (use C-x C-f). Delete any text that appears in ALL CAPS and type in appropriate information.

Rearrange the verses of the song in the correct order. Here is the procedure for moving a verse:

1.        Move the cursor to the beginning of the verse.

2.        Type C-SPC (`Control space-bar') to set the mark.

3.        Use the arrow keys to move the cursor to the end of the verse.

4.        Type C-w to kill (cut) the region.

5.        Move the cursor to the correct location for the verse.

6.        Type C-y to yank (paste) the killed text into place.

When you have finished editing the silly_song buffer, save your work using C-x C-s. Make a printout of the updated file by entering the command

lpr silly_song

The printer is located in room C 07. Make sure you pick up your own printout--other students will be printing files that look similar.

Shut down the Emacs program with C-x C-c.

Exercise C: Editing, compiling and running a C++ program

Read This First

New Unix commands:

1.        g++   source_file

compile and link C++ program with library file, creating executable file called a.out

You can use the command to compile several source files. For example:

g++ file1.cpp file2. cpp file3.cpp

Compiles three source files, file1.cpp, file2.cpp, and file3.cpp and creates the executable file called a.out

2.        g++ -o myprog source_file(s)

same as above, except that the executable will be called myprog

What to do

Within your lab1 directory, make a new directory called exC

Copy the three files from /nfs/home/engg335/lab1/exC into your lab1/exC directory. Use the more command to take a quick look at these files, which together form a very simple C++ program. Compile it with the command

g++ exCmain.cpp hello.cpp

Using the ls command, you should be able to see that a new file called a.out has been created; this is the executable version of the program. Run it, using the command

./a.out

Note: To run a program in the working directory, you must put ./ in front of the name of the program. In the Common Core labs, the shell has been configured so that it will not search for programs in the working directory unless it is explicitly told to look there.

Now start up Emacs. Load the file hello.cpp into Emacs, and modify it so that it uses your own name when it displays its greeting on the screen. Save the file, and exit Emacs.

Re-compile the program, this time with the command

g++ -o exCprog exCmain.cpp hello.cpp

If there were errors, go back to Emacs and fix them. (Ask for help if necessary!) Otherwise, use the ls command to discover that a new executable called exCprog has been created. Run this executable by entering ./exCprog as a command.

Using Emacs, add a line to the program so that it says Good-bye after it says I am a C++ program. Save the file, re-compile your program, and make sure it works. Then shut down Emacs.

Exercise D: Getting rid of executables

Read This First

Space in our Linux file system is limited. For this reason, you should always get rid of large unneeded files.

Unix command to delete one or more files:

1.        rm filename(s)
delete files listed on command line

Unix systems do not in general have a `trash can' or an `undelete' command. If you delete a file with rm, it's probably gone forever.

What to do

What are the sizes of all of the files in your lab1/exC directory? 

Note that the executable files are by far the largest, and that executable files can easily be created again by re-compiling the source files. For this reason, it is a good idea to make a habit of deleting executable files if you think you won't be using them again. Source files, on the other hand, are small, and must be laboriously re-typed if they are lost, so it is best not to delete them.

(Files downloaded from the Internet can also be quite large. Please don't waste disk storage by storing a lot of these files on the system.)

Use the rm command to delete a.out and exDprog. Use ls to make sure that they are really gone.

 

Exercise E: Using Emacs

Read This First

The purposes of this exercise are:

1.        to show you how to use Emacs;

2.        to get used to the idea of editing more than one file in a single Emacs session;

3.        to help you remember what you learned in Exercises A through D by making you repeat some of the procedures you performed in those exercises.

Emacs was designed before graphical user interfaces were in wide use, so it's easy to get things done in Emacs without a mouse. However, most users find that a few Emacs actions are more convenient with a mouse.

What to do

By typing commands in the xterm window, create a directory called exE within your lab1 directory. Copy all three files from /nfs/home/engg335/lab1/exE into your lab1/exE directory.

The files are the source for a small C++ program. Build an executable and run it.

Start Emacs with the command

  emacs & 

Notice that this creates a new window. The & puts Emacs `in the background', which means that the xterm window can still be used for commands. To confirm this, type ls in the xterm window.

One at time, load each of the files main.cpp, the_func.h and the_func.cpp into Emacs. (Just use C-x C-f three times and give a different file name each time.)

Practice using the Buffers menu to switch between the three C++ files. Also practice using C-x b to switch buffers without using the mouse.

Use Emacs to edit all three files:

1.        Change the name of the function foo to the more descriptive print_3_lines. (This involves editing code in more than one file.)

2.        Your name, ID number, and lab section number should appear in the comments at the top of the files.

3.        The three lines of output produced by the print_3_lines function should appear in the proper order.

Once you think you have done all the necessary editing, save all the modified files.

The easiest way to save all your changes is to use C-x s. Note that C-x s is different from C-x C-s; C-x s lets you save several files at once. When you use C-x s, you must type y each time you are asked whether or not you wish to save a file.

Compile and run your modified program. If there are errors, go back to Emacs and fix them.

When you have finished, make printouts of the three modified source files.

 

 

Exercise F: Checking for input failure

Read This First (Part I)

It's important to understand that cin is an object that manipulates a sequence of characters. Each time your program successfully gets some input from cin, cin consumes only as many characters as are needed to satisfy the request for input. It's also possible for a request to fail; that's discussed in more detail in Part II below.

Consider this example program:

#include <iostream>
using namespace std;
int main()
{
  int a = 0, b = 0, c = 0;
  cout << "Please enter three numbers:\n";
  cin >> a;
  cin >> b;
  cin >> c;
  cout << "You entered " 
       << a << ", " << b << " and " << c << ".\n";
  return 0;
}

Here's a sample dialog with this program. The first and third lines are program output; the second is user input:

Please enter three numbers:
123 456 789
You entered 123, 456 and 789.

That shouldn't be hard to understand, as long as you realize that the characters '1', '2' and '3' are consumed by the first input operation and that all the remaining characters on the line are left to be consumed by future input operations

But now look what happens when the user doesn't realize that the program can only handle integers:

Please enter three numbers:
12 3.4 56
You entered 12, 3 and 0.

What happened? Here's what cin's stream of characters looks like after the first input operation:

cin consumed the characters '1' and '2' because those were digits that are part of the textual representation of an integer. It then read the first space, and put it back on the stream because a space is not part of the textual representation of an integer. cin used the digits '1' and '2' to compute a value of 12 for a. Now, here's a picture showing the stream after the second input operation:

The first space was consumed because the rule is to consume and discard spaces while looking for the beginning of a number. The '3' was consumed as part of the textual representation of an integer. The '.' was read and put back on the input stream; textual representations of integers in C++ input don't contain decimal points. cin used the digit '3' to compute a value of 3 for b. The third input operation failed because the character '.' can't be the beginning of integer input; this is why c maintained its initial value of 0.

Read This First (Part II)

When you read input from an input stream, C++ allows you to check whether the most recent input operation actually worked. Here are some reasons why input could fail:

·         The program is reading from a file, and an attempt has been made to read past the end of the file.

·         The wrong kind of character is found in an attempt to read using a specific format. For example, if the program is trying to execute

·                                                  cin >> x;
      

where x is an int, input will fail if the next non-whitespace character is not a minus sign, a plus sign, or a digit. (Whitespace characters are characters such as space, tab and newline; the name comes from the fact that they appear as white space when printed on a piece of paper.)

·         Something bad happens with the hardware or the operating system. For example, if the program is reading from a file on a floppy disk, and the user removes the disk from the drive while the file is still open, input will fail.

Once there has been a failure on an input stream, all future operations on the stream will also fail, unless you perform a clear operation on the stream. (Reliance on clear operations leads to messy code, and is not recommended.)

Input is said to ``fail silently'', which means that unless you add code to check for input failure, your program will repeatedly fail to get input and may go into an infinite loop or generate incorrect output.

To check if input has failed, you can use the fail member function. This leads to code like this:

  if ( cin.fail() )
  {
    // do something about the failure
  }

or this:

  while ( !cin.fail() )
  {
    // get some input and do something with it
  }

C++ allows some type conversion trickery which lets you write the above fragments in slightly shorter forms:

  if ( !cin ) // here !cin is equivalent to cin.fail()
  {
    // do something about the failure
  }

or this

  while ( cin ) // here cin is equivalent to !cin.fail()
  {
    // get some input and do something with it
  }

It's important to realize that an input stream only goes into the ``fail state'' after an attempt to read input has failed. If you forget about this, you may write code that detects input failure ``just a little bit too late.''

The member function eof is used to test whether an attempt has been to read past the end of the input file. If input fails for some reason other than end-of-file, eof will return false.

Read This First (Part III)

In Unix, MS-DOS, and MS Windows ``Consoles'', you can redirect standard input (corresponding to cin in C++) and standard output (corresponding to cout in C++) to come from or go to files. Suppose you have an executable called myprog that reads input from cin and writes output to cout. Then the command

    ./myprog

reads keyboard input and generates screen output. The command

    ./myprog < input

reads input from the file input.txt and generates screen output. And the command

   ./myprog > output

gets keyboard input and puts its output in the file called output

Similarly the command

   ./myprog <input  >output

reads input from the file called input and writes the program’s standard output (output the screen) into the file called output.

Unix allows many useful variations on this basic idea. See Unix documentation for details.

Read This First (Part IV)

Some students get confused about the differences between break, return, exit and abort. This confusion can cause severe problems in understanding what a program is doing.

Here is a brief description of what these things mean:

·         A break statement causes the flow of control to jump to the end of a loop or switch statement.

·         A return statement causes a function to terminate immediately.

·         A call to the exit function causes a program to terminate immediately. This happens regardless of whether exit is called from main or from some other function. To call exit you should put

·                              #include <stdlib.h>

in your source file. The call

  exit(0);

tells the operating system that the program was successful, while the call

  exit(1);     

tells the operating system that the program failed in some way.

·         A call to abort also causes a program to terminate immediately. Calling abort also requires the use of

·                              #include <stdlib.h>
      

abort is different from exit in that it is generally used to report an unexpected failure that may indicate the need to do some debugging. In Unix, if a program calls abort, it will generally leave behind a core file. The abort function doesn't take arguments, so the syntax for a call is simply

  abort();  

What to do

Before you start, remember that most Unix programs that are in an infinite loop or are otherwise ``hung'' can be terminated by typing control-C.

Step 1. Make a copy of the directory /nfs/home/engg335/lab1/exF and its contents. You should find two .cpp files and two data files. The two .cpp files are separate programs.

Step 2. View the contents of dataA.txt with more. Build an executable called prog_one from the source file prog_one.cpp. Run it with the command

  prog_one  <  dataA.txt

Why does the program produce the wrong answer? To find out, look at the program source code; if necessary, add more output statements to get more information about what is going on. Write an answer (three or four short sentences) to hand in with this assignment.

Step 3. Now create an executable called prog_two from the file prog_two.cpp. Run it with the command

  ./prog_two  <  dataA.txt

You should see that this program does not have the same bug as prog_one. However, it is not bug-free. Try this command:

  ./prog_two  <  dataB.txt

What happens when dataB.txt is used as input to prog_two? Write an explanation (three or four short sentences) to hand in with this assignment.

Step 4. Finally, write a program that doesn't have the flaws of either of the two given programs. If the input consists of nothing but integers separated by white space, the program should compute and display the average of all of those numbers. If there is some kind of error in the input, the program should display an error message and not even try to compute an average.

Make a printout of your program, and hand that in along with answers to the first questions asked in Steps 2 and 3.

Exercise G: Nested loops

Read This First

The main point of this exercise is to give you practice in solving problems using nested loops.

Also gives you some practice in using controlling the appearance of numbers when they are printed. (See Section 11.3.1 of Skansholm for more information on this topic.) This is one of the less pleasant areas of C++. The rules are complicated and have been evolving over the past year, so even if you understand clearly what your textbook is saying, your compiler system may behave in a way different from what you expect. We will not test you on controlling field width and precision in numerical output on the midterm test or final exam.

(Note: This is the last ENGG 335 exercise that primarily provides drill on concepts you should have learned in a previous course.)

What to do, Part I

Make a copy of the file /nfs/engg335/lab1/exG/formats.cpp
Study the code, then build an executable and run it. The behavior of the program should provide useful hints for the second part of this exercise.

What to do, Part II

Write a C++ program to print the following table:

 
Table of sin(theta), where theta is given in degrees
 
        0            1            2         3          4          5          6         7          8          9
 0    0.000   0.017   0.035   0.052   0.070   0.087   0.105   0.122   0.139   0.156
10   0.174   0.191   0.208   0.225   0.242   0.259   0.276   0.292   0.309   0.326
20   0.342   0.358   0.375   0.391   0.407   0.423   0.438   0.454   0.469   0.485
30   0.500   0.515   0.530   0.545   0.559   0.574   0.588   0.602   0.616   0.629
40   0.643   0.656   0.669   0.682   0.695   0.707   0.719   0.731   0.743   0.755
50   0.766   0.777   0.788   0.799   0.809   0.819   0.829   0.839   0.848   0.857
60   0.866   0.875   0.883   0.891   0.899   0.906   0.914   0.921   0.927   0.934
70   0.940   0.946   0.951   0.956   0.961   0.966   0.970   0.974   0.978   0.982
80   0.985   0.988   0.990   0.993   0.995   0.996   0.998   0.999   0.999   1.000

(To use to the table to find the sine of, for example, 35 degrees, you would look for the row starting with 30, then move across to the column for 5, giving you a value of 0.574.)

Notes about sin:

·         The prototype for the sin function is in the <math.h> header file.

·         The argument of sin is given in radians, not degrees.

Hand in a printout of your source code and a printout of the table it prints.

To print the table, run your program, and save the table in an output file. For example if your program’s executable file name is myprog, try the following command:

./myprog > myOutputFile

Now you can use the Linux lpr command to print the file myOutputFile.