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.
Please read this handout carefully before
coming to the lab.
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.
The lab will start every at
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
The following
rules apply to this lab and all other lab assignments in future:
ENGG 335 Lab 1Lab 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.
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:
``Dot'' and ``dot dot'' are both used frequently in Unix commands.
Some Unix commands:
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!
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:
create directory with name dirname in the working directory
copy file filename into directory dirname
start GNU Emacs `in the
foreground'--necessary if you are not using the X Window System
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 cursorDelete 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 regionC-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.
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.
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.
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.
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 789You 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 56You 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.
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.15610 0.174 0.191 0.208 0.225 0.242 0.259 0.276 0.292 0.309 0.32620 0.342 0.358 0.375 0.391 0.407 0.423 0.438 0.454 0.469 0.48530 0.500 0.515 0.530 0.545 0.559 0.574 0.588 0.602 0.616 0.62940 0.643 0.656 0.669 0.682 0.695 0.707 0.719 0.731 0.743 0.75550 0.766 0.777 0.788 0.799 0.809 0.819 0.829 0.839 0.848 0.85760 0.866 0.875 0.883 0.891 0.899 0.906 0.914 0.921 0.927 0.93470 0.940 0.946 0.951 0.956 0.961 0.966 0.970 0.974 0.978 0.98280 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.