Project 0: Intro project

This project serves as an introduction to developing and compiling C programs, as well as to the build, testing, and submission framework used in this class. A more complete description of the project framework is contained in the project guide, which you should read in full before completing P1.

Before proceding, you should also first complete the compilation lab.

Unit Requirements

Here are the functions that you must implement in p0-intro.c:

  • int add_abs (int num1, int num2)

    Returns the sum of the absolute values of the two parameters.
  • void add_ptr (int num1, int num2, int *ans);

    Add two numbers and store the results in ans. Does nothing if the pointer is null.
  • int factorial (int num);

    Return the factorial of non-negative inputs; otherwise, returns 1.
  • bool is_prime (int num);

    Return true if the input is a positive prime number, false otherwise.
  • vector_t add_vec (vector_t v1, vector_t v2);

    Add two vectors. (See p0-intro.h for the definition of a vector_t)
  • double dot_prod_vec (vector_t v1, vector_t v2);

    Return the dot product of two vectors.
  • int sum_array (int *nums, size_t n);

    Return the sum of all numbers in an array of length n.
  • int gcd (int num1, int num2);

    Return the greatest common divisor (gcd) of the two inputs. For our purposes, we will define that the gcd of zero and any other number x to be x (i.e., gcd(a,0) = a and gcd(0,a) = a, which also means that gcd(0,0) = 0). Implementation hints here.
  • void sort_array (int *nums, size_t n);

    Sort an array of length n. You may use any sorting algorithm you wish; we recommend keeping it simple.

There are several unit tests for these functions; some are public and you can view the source code in tests/public.c, while others are private, meaning you do not have access to the source code. This will be the case for all projects in this course--it is important that you learn to anticipate edge cases and other errant behavior.

Integration Requirements

When run, the program should print the text "Hello, world!" followed by a newline character ("\n"). This will require you to edit the code in main.c.

The remaining integration requirements will require you to add new functionality that is activated using command-line switches. You should implement these features as modes in main.c. Some of these modes require parameters, which are passed as command-line arguments. We recommend using getopt to handle command-line parsing.

Multiple modes may be active at once, and if any mode is activated, the original "Hello, world!" message should not print. If multiple modes are activated, their output should be printed in the order they are listed below. If a mode with a parameter is activated multiple times (via multiple command-line switches), ONLY the last parameter should be used. Any switch not described here should cause the message "Invalid argument." to be printed and the program should exit immediately with no further output.

Here is a list of modes in order of their output:

  • Goodbye mode ("-g")

    Print "Goodbye!"
  • Cat mode ("-c <file>")

    Print each line from the given file to standard out, similar to the Unix cat utility. If no filename is provided, print "Invalid argument." and exit with no further output. If a filename is provided but the file cannot be opened, print "Invalid file." and exit with no further output.
  • Triodd mode ("-t <n>")

    Count from one to n (one number per line), printing "odd" if the number is odd, "tri" if the number is divisible by three, and "triodd" if the number is both. Otherwise, just print the number itself. If no number is provided, print "Invalid argument." and exit with no further output.
  • Uniq mode ("-u <file>")

    Print each line from the given file to standard out, but remove sequential duplicates. In other words, don't print the same line twice in a row. This mode should perform the same as cat mode in the case of a missing or invalid filename.


To run the provided tests, use the "make test" command from the project folder. At first, your output will look like this (some output omitted for brevity):

             UNIT TESTS
15%: Checks: 20, Failures: 17, Errors: 0
public.c:12:F:Public:D_addabs_simple:0: Assertion 'add_abs(2,3) == 5' failed [...]
public.c:21:F:Public:C_addptr_simple:0: Assertion 'ans == 5' failed [...]
public.c:19:F:Public:C_factorial_simple:0: Assertion 'factorial(1) == 1' failed [...]
public.c:33:F:Public:C_isprime_simple:0: Assertion '!is_prime(4)' failed
D_hello                        FAIL (see outputs/D_hello.diff for details)
C_goodbye                      FAIL (see outputs/C_goodbye.diff for details)
No memory leak found.

The test case names have been highlighted in the output above. After you finish the project, the output should look like this:

             UNIT TESTS
100%: Checks: 20, Failures: 0, Errors: 0
D_hello                        pass
C_goodbye                      pass
No memory leak found.

Note that in this project, the "integration" tests don't really test for successful integration of smaller program units; they test entirely separate functionality. This will not be the case in the rest of the projects.


  • Read and ask questions early. If there is any part of this document or the project files that you do not understand, you should ask it on Piazza as soon as possible.
  • Start work early. You will be unable to finish this project if you leave it to the last few days before it is due. Set up your project work folder as soon as possible.
  • Follow test-driven design. Before you write a single line of code, create test cases based on the output specification described above. Do NOT write any code without having a test case ready to test your code. We have provided tests but they may be difficult for you to understand. Creating your own tests means that you will be better able to identify what is wrong.
  • Use version control. Learn Git or Mercurial and keep your code in a repository. It will save you much time and anguish if you ever accidentally delete something. If you use an online service such as Github or Gitlab, make sure you create a private repository. Posting project solutions publicly is a violation of the honor code in this course.
  • Learn to use a debugger. Debuggers allow you to "poke around" while your program is running to figure out where your mental model of the program differs from reality. This will make fixing problems much easier.


Your submission will receive a baseline grade determined by the automated test results as follows:

Grade Requirements
  • Correct sort_array()
  • Correct triodd mode output
  • Correct uniq mode output
  • All of the below.
  • Correct add_vec()
  • Correct dotprod_vec()
  • Correct sum_array()
  • Correct gcd()
  • Correct cat mode output
  • All of the below.
  • Correct add_ptr()
  • Correct factorial()
  • Correct is_prime()
  • Correct goodbye mode output
  • All of the below.
  • Correct add_abs()
  • Correct "Hello world!" standard mode output

Additionally, penalties may be imposed if you have inconsistent formatting, incorrect or non-existent documentation, a memory leak, or any other violation of the course style guidelines and security restrictions.


Due: Fri, Sep 13 at 23:59:59 ET (midnight)

You must submit your files from stu. To submit, run the following command from your project directory:

/cs/students/cs261/f19/ p0

Please see the project guide for general project help. Please refer to the coding standards for coding practice guidelines.