CMSC 106 Project #3 Fall 2001

Due date: 11:00 pm on Sunday, October 21, 2001.

1. Purpose

In this project you will write a program using loops and nested loops. Although as a matter of style and clarity it is usually extremely important to determine the most appropriate type of loop for each iterative task in a program, in order to get practice with all of C's loop statements it is suggested that you intentionally use several types in your project.

You are developing a program to help predict the movement of hurricanes. Because the model you are using does not include the physics of atmospheric motion, the program applies some simple rules which depend on whether the storm is over water or over land. In order to handle different shapes of coastlines, the model uses several simplified patterns of land and water. Starting with a particular map pattern and the initial conditions for the hurricane, the program will print out the predicted movement and strength of the storm. When the hurricane reaches a point where it would move off the edge of the map, the program will print out the map, showing the final position of the storm.

2. Project description

As you read this section, you may also want to refer to the ``Sample output'' section below.

The input to your program is to consist of a sequence of groups of input lines (redirected from an ASCII text file using UNIX standard input redirection). The first line of each group will consist of three integers:

The second line will consist of two integers, the row and column which represent the starting position of the hurricane. The row along the northern (top) edge of the map is row 0, and the column along the western (left) edge of the map is column 0. The program may assume that the row and column values are valid for the current map.

The third line will consist of two integers, the starting barometric pressure in millibars and the wind speed in knots. The program may assume that the pressure and wind speed are correct.

The program will read the input lines and then print out the predicted movement (row and column) of the storm and its strength (barometric pressure and wind speed) until the predicted storm movement would be beyond the edge of the map. The position and strength must be printed in neatly aligned columns, as shown in the sample output. Then the program will print out the map, showing the areas of land and water and the final position of the storm. The program will continue reading input lines and printing storm predictions and maps until it reads an input line which contains a map type of 0. The last line will be complete (contain 3 values), but the program will do no further processing once that line is read.

Valid map types, their descriptions, and examples are the following:

Hint: For drawing map type 4 or 5, look for a relationship with types 2 and 3.

All of the land points on the map are to be printed using '*' and all of the water points are to be printed using '-'. Note that the "square" maps will not actually appear square when they are printed, since the height of a printed row is greater than the width of a character. No map can be printed which has more than 20 rows or 30 columns.

2.1 Program output

If any group of input lines contains an incorrect map code your program must print an explanatory error message and read a new group of input lines without processing the data values for the incorrect map. This explanatory error message must be printed all on one line and contain the exact word ``ERROR'' followed by the two words ``Map Code'' followed by the invalid input value.

If the map code is valid, but the input line contains an invalid set of map dimensions, your program must print an explanatory error message without processing the data values. This error message must be printed all on one line and contain the exact word ``ERROR'' followed by the word ``Size'' followed by the invalid input values. If both the map code and map dimensions are invalid, then only the message for the map code is to be printed.

Before each set of output (hurricane forecast or error message), a line must be printed to tell the person who is reading the output which set of input lines the output that follows corresponds to. The line must first have an integer (starting with 1 for the first set of input lines) followed immediately by a space which is then followed by a series of exactly 20 plus signs ('+'). This line must be followed by a blank line.

Following the output header message, the program must print the forecast for the hurricane's movement and strength, followed by a map which shows the hurricane's final position. The forecast is determined by the following rules:

Following the list of storm positions and strength, the program must print a blank line. Following the blank line, the program must print a map of the correct size showing the location of land and water points. The final position of the hurricane must be shown with a zero ('0'). The rows are to be labeled, starting with 0 in the north (top). There is to be a single space between the row labels and the points in a row. The columns are to be labeled, starting with 0 in the west (left). Note that if the column number is more than 1 digit, the label must be arranged vertically, since the width of the columns is only 1 character.

The program must continue reading and processing groups of input values until the end of the input is reached as described earlier.

3. Project requirements

All your C programs in this course should be written in ANSI C, which means they must compile and run correctly with cc -std1 -trapuv on the OIT UNIX Class Cluster. You will lose credit if your program generates any warning messages when it is compiled. Even if you already know what they are, you may not use any C language features other than those introduced in Chapters 1 through 6 of your textbook, plus those presented in lecture while these chapters were covered. Note that as a result arrays and user-defined functions may not be used. In addition, neither the goto nor the continue statement may be used, and the break statement may not be used in any loop. Lastly, your program must contain only one single return statement at its end, and may not use the exit() function at all. Using C features not in these chapters, or using the goto statement, multiple returns, or break or continue in loops will result in losing credit.

Your program must have a comment near the top which contains your name, login ID, student ID, your section number, your TA's name, and an original description of the action and operation of the program. Do not put your alias in this comment! Your program should be written using good programming style and formatting, as discussed in class and throughout your textbook. For this project, style is considered to consist of:

4. Deadline

Your project must be electronically submitted by the deadline stated above to avoid losing credit per 24 hours as indicated on the syllabus. No project more than 48 hours late will be accepted without prior permission or a valid medical excuse, as described on your syllabus. Lost passwords or other system problems do not constitute valid justifications for late projects. You should start working on your project now!

5. Developing your program

You may want to skip this section at first, read the rest of the project, and come back to study it carefully when you are about to begin writing your program.

One of the important skills which must be learned in this course is how to track down the causes of and fix both syntax and semantic errors in your code. As your program will inevitably have many errors while you are developing it, you will need to follow procedures such as those described below before coming to office hours for assistance. Should you still not be able to solve the problem and have to come to office hours, you will be required to clearly describe your error and what you have already done to try and find it, and bring current printouts of your source code, and any compiler errors or execution results.

5.1 Possible development steps

As mentioned in the earlier project assignments it is extremely important to type in only a part of your program at a time and compile and test it to verify that it is correct before going on. Different choices can be made in selecting which parts of a program to implement first; the following is just one possibility. It's fine if you prefer to follow different steps, but whichever order you choose to develop your program it is essential to enter small parts at a time and test each one before going on!

  1. The first step in developing a program very often should be to read the required input values and just print them out to verify that they were read correctly. If your program isn't reading its input properly, obviously no subsequent processing can ever be correct. Also make sure the program can stop when it reads a 0 as the map code. At this point you can also get the numbering (dividing lines) printing in the output counting the input lines as it goes.

  2. Next you may want to assume the user will put in valid input (for the map code and the dimensions). Make sure the input files you create for this stage do not contain any invalid values.

    Be sure to compile and thoroughly test the code implementing this step (in fact, you could implement this step itself in several substeps, testing each as you go). These substeps could include assuming the user will only ask for the first type of map. Take each step allowing more flexibility in the input - make sure you have the correct values in your input file for whichever level you are assuming at that time.

  3. Then expand your program so it can include the other map types.

  4. Then expand your program so that it can determine invalid input and responds correctly.

5.2 Finding compilation errors

  1. If you implement your project in sections as described above, a syntax error which appears will most likely be caused by something in the code which was most recently added. Start by looking at these lines and the lines directly adjacent to them.

  2. Some types of syntax errors (such as missing or mismatched braces) can't be recognized by the compiler until some point in the program after the actual mistake, sometimes not even until the end of the program file. If a syntax error is identified at the end of your program, or if a syntax error is generated for a seemingly correct line, this type of error might be the cause, so examine your braces carefully, making sure they all match up properly

    A useful strategy to use for narrowing down the cause of such types of errors is to comment out one section of the program at a time and recompile it after each part is commented out, until the syntax error goes away. At that point, the cause of the error must be in the most recently commented-out code. If you comment out parts of your code your program certainly won't work correctly, but this technique is just to help you quickly find the syntax error, and once you correct it you can just remove the /* and */ symbols which you added to comment out your code.

    A few things to keep in mind about this technique are as follows. You can't comment out only a part of a larger statement, for instance, you can't comment out the first half of an if statement but leave the else part- you would have to comment out the whole if/else. You can't comment out half of a compound statement such as the opening brace ({) and some of the statements inside but leaving the closing brace (}) uncommented as part of the code- you would have to comment out the whole compound statement. You also can't comment out code containing comments- you would have to copy your program to a different file, delete the comments, and then use this strategy. Once you find the syntax error in this temporary copy of your program you can correct it in your real version.

5.3 Creating files for input redirection

A file used for UNIX input redirection (using the < symbol after the name of a program being run) is just a text file which you can create with any UNIX text editor (e.g., emacs). You type the exact lines to be used for the program's input the same way you would have typed them from the keyboard while the program was running if you were not using input redirection. To run the program with different input you can modify the file or create a new one with different contents.

The newline character will not be visible at the end of each line of the input file you create. It is necessary that there be a newline character at the end of the last input line, so be sure you press the return (or enter) key at the end of the last line of any file you create containing input values you are going to test your program with. Otherwise your program may not work properly in some circumstances.

5.4 Program debugging

  1. If your loops don't work as you expect, add debug printf statements. Since you are writing a program to draw something, the debug printf output will prevent your map from being displayed correctly, but it can help you figure out why your program is wrong and the debug printfs can be easily removed after that.

  2. If your program just stops and doesn't produce any results, it has either paused to wait for input from the user or you have an infinite loop. Another symptom of an infinite loop is a program which keeps printing the same thing over and over. Since your program will contain many loops you may not be sure which one causes the error. If you add a different debug printf statement inside the body of each loop and run your program again, the printf which gets repeated identifies which loop is the infinite one. If no line gets repeated, the infinite loop was either missed when you added the debug printfs or this loop does not have a body. An extra (unwanted) semicolon in the wrong place can cause the loop to have a null (empty) statement for its body.

  3. For technical reasons not worth explaining in full detail here, not all of your program's output will appear on the screen (or redirected output file) until a newline is printed. When a program produces output it isn't displayed directly on the screen. For efficiency and other reasons, output generated is saved internally (by the operating system) until a certain amount is present, and it's then all printed. This means that if a program contains an infinite loop, or has a fatal error, you may not see the results of the most recent output statements. You might think the program is having trouble at one point because it contains some printf statements and you didn't see their results printed, so the problem would seem to be above that point in the program. However, it could be that those statements were executed, but their results were just not displayed on the screen because the infinite loop or fatal error occurred soon afterwards in the program.

    It may sound like it's a difficult debugging problem to even figure out where in your program an error occurs, if printf results may or may not appear on the screen, but there is an easy way to see all of a program's output at any time. If a newline character (\n) is printed, then any pending output which has not actually been displayed yet will be immediately printed. So if your program seems to have an infinite loop (or a fatal error), either simply print some newlines, or even better, as mentioned above, add debug printf statements to every loop to see which one has the problem- but make sure each such debug printf ends in a newline character! Extra newlines or debug printf results will probably cause your output to appear incorrect, but at least they will help you figure out where your program's error is, and the extra print statements can be easily removed later.

  4. If you still can't figure out why your program doesn't work after you have thoroughly tried debugging it using these techniques, bring current printouts to office hours and we can teach you how to track the problem down.

    If there is any chance you may ever have to come to office hours, you should make your code readable from the very beginning. You should be able to easily understand it, and so should your instructor or a teaching assistant in office hours. If your code is a mess, the teaching assistants will direct you to first clean it up before returning so they can understand it and be able to help you. Naturally you want your code to be clear and easily readable by the graders after you have submitted it as well.

6. Academic integrity statement

Any evidence of unauthorized use of computer accounts or cooperation on projects will be submitted to the Student Honor Council, which could result in an XF for the course, suspension, or expulsion from the University. Projects are to be written INDIVIDUALLY. For academic honesty purposes, projects are to be considered comparable to a take-home exam. Any cooperation or exchange of ideas which would be prohibited on an exam is also prohibited on a project assignment, and WILL BE REPORTED to the Honor Council.


  1. failing to do all or any of the work on a project by yourself, other than assistance from the instructional staff.

  2. using any ideas or any part of another student's project, or copying any other individual's work in any way.

  3. giving any parts or ideas from your project, including test data, to another student.

  4. having programs on an open account or on a PC that other students can access.

  5. transferring any part of a project to or from another student or individual by any means, electronic or otherwise.


7. Submitting your project

Turn in your program using the ``submit'' program as before, except using ``3'' for the project number. You are to submit only the .c file containing your source code, not the executable version of your program! If your program is in a file named storm.c, submit would be run as shown. Don't forget to read the class announcements in your instructor's account every time you log in.

% submit  3  storm.c

Before you submit your project, you must exactly follow the specific submission checklist in the ``Testing projects before submitting'' handout separately posted by your instructor!

8. Sample Output

If the name of the executable version of your program is storm.x, here is a sample execution for the input data shown. Each of the three sample sessions show the input file and then what the program does when run with that input file. The first column is what we will be grading as the primary input - the other two are just to show other output for more advanced features of your program.

Be sure to test your program against a variety of data, so you are sure it works in all circumstances!

% cat p3.in1

1 7 10
6 5
1000 75
2 9 9
7 7
990 80
3 8 8
7 6
1005 70
0 0 0

% storm.x < p3.in1

1 ++++++++++++++++++++

Row  Column     Pressure   Wind
  6       5      1000 mb  75 kt
  6       4       997 mb  80 kt
  5       3      1000 mb  75 kt
  4       2      1003 mb  70 kt
  3       1      1006 mb  65 kt
  2       0      1009 mb  60 kt

 0 *****-----
 1 *****-----
 2 0****-----
 3 *****-----
 4 *****-----
 5 *****-----
 6 *****-----

2 ++++++++++++++++++++

Row  Column    Pressure   Wind
  7      7       990 mb	 80 kt
  6      6       993 mb	 75 kt
  5      5       996 mb  70 kt
  4      4       999 mb  65 kt
  3      3      1002 mb  60 kt
  2      2      1005 mb  55 kt
  1      1      1008 mb  50 kt
  0      0      1011 mb  45 kt

 0 0--------
 1 **-------
 2 ***------
 3 ****-----
 4 *****----
 5 ******---
 6 *******--
 7 ********-
 8 *********

3 ++++++++++++++++++++

Row  Column    Pressure   Wind
  7      6      1005 mb	 70 kt
  7      5      1002 mb	 75 kt
  7      4       999 mb	 80 kt
  7      3       996 mb	 85 kt
  7      2       993 mb	 90 kt
  7      1       990 mb	 95 kt
  7      0       987 mb	100 kt

 0 ********
 1 *******-
 2 ******--
 3 *****---
 4 ****----
 5 ***-----
 6 **------
 7 0-------


% cat p3.in2

6 7 10
6 5
1000 75
1 9 9
7 7
990 80
0 0 0

% storm.x < p3.in2

1 ++++++++++++++++++++

ERROR: Map Code 6

2 ++++++++++++++++++++

ERROR: Size 9 9

% cat p3.in3

4 15 15
7 6
1005 70
0 0 0

% storm.x < p3.in3

1 ++++++++++++++++++++

 Row  Column  Pressure  Wind
  7       6    1005 mb  70 kt
  6       5    1008 mb  65 kt
  5       4    1011 mb  60 kt
  4       3    1014 mb  55 kt
  3       2    1017 mb  50 kt
  2       1    1020 mb  45 kt
  1       0    1023 mb  40 kt

 0 *--------------
 1 0*-------------
 2 ***------------
 3 ****-----------
 4 *****----------
 5 ******---------
 6 *******--------
 7 ********-------
 8 *******--------
 9 ******---------
10 *****----------
11 ****-----------
12 ***------------
13 **-------------
14 *--------------

Steve Scolnik