CS31 Lab 2: C Warm-up: Sorting

Due before 11:59pm, Tuesday, Sept. 19

This lab should be done with your assigned partner:

Lab 2 Goals:

Contents:

Working with Partners
For this and all subsequent lab assignments in this class, you will work with a partner. We will assign partners for the first few labs, and then give you an opportunity to choose your partner with whom you will work for the rest of the semester.

The expectation is that you and your partner are working together side by side in the lab for most, if not all, of the time you work on a lab assignments. You and your partner should work on all aspects of the project together: initial top-down design, incremental testing and debugging, and final stress testing and code review. There may be short periods of time where you each go off and impelement some small part independently. However, you should frequently come back together, talk through your changes, push and pull each others code from the repo and try out your merged code together. Taking time to design a plan for your solution together and to do incremental implementation and testing together may seem like it is a waste of time, but in the long run it will save you a lot of time by making it less likely that you have design or logic errors in your solution, and by having a partner to help track down bugs and to help come up with solutions to problems.

Partnerships where partners work mostly independently rarely work out well and rarely result in complete, correct and robust solutions. Partnerships where partners work side-by-side for all or most of the time tend to work out very well.

You and your partner are equally responsible for scheduling times when you can meet to work together, and for making time available in your schedule for working together.

Lab 2 Starting Point Code

Both you and your partner should do:

  1. Get your Lab2 ssh-URL from the GitHub server for our class: CS31-F17
  2. On the CS system, cd into your cs31/labs subdirectory
    cd ~/cs31/labs
    
  3. Clone a local copy of your shared repo in your private cs31/labs subdirectory:
    git clone [your_Lab2_URL]
    
If all was successful, you should see the following files when you run ls:
ls
  Makefile       README.md   floats2.txt  floatsbig.txt  readfile.h
  QUESTIONNAIRE  floats.txt  floats3.txt  readfile.c     sorter.c
If this didn't work, or for more detailed instructions see the the Using git page.

As you and your partner work on your joint solution, you will want to push and pull changes from the master into your local repo.

We will do this together in Wednesday lab:
Try out git push and pull before working on lab 2 code:

  1. Both of you add some minor change to the program like printing out your name in the main function.
  2. Both compile and run and make sure your change doesn't break the code.
  3. Both do a git add and a git commit.
  4. One of you try doing a git push.
  5. Then the other try doing a git pull (you should see your partner's code). Compile run and test it out. Now do a git add, git commit, git push.
  6. Now, first pusher do git pull to pull changes into their local.

Also, it is good practice to do a make clean before doing a git add and commit: you do not want to add to the repo any files that are built by gcc (e.g. executable files). Included in your Lab2 git repo is a .gitignore file telling git to ignore these files, so you likely won't add these types of files by accident. However, if you have other gcc generated binaries in your repo, please be careful about this.


Lab Overview

You will implement program that sorts floating point numbers using a sorting algorithm of your choice in C. Your program will read a collection of unsorted floats from a file, store those floats in an array, provide some information about the floats to the user, sort them from smallest to largest (i.e., ascending order), and print them out in sorted form to the user.

Lab 1 Starting Point Code

  1. Makefile: Use it to compile your code (and to clean it up).
    make
    make clean
    
    We will look at writing Makefiles later in the semester. You're welcome to look at its contents now, but you do not need to edit it for this lab.

  2. readfile.h and readfile.c:These files contain a library for reading from files. You should make calls to functions in this library in your program. The instructions for using this library are explained below. Later in the semester you will write your own library code, but for this assignment you will just use this readfile library code that is already written for you.
    You should not modify any code in these two files.

  3. sorter.c: the file into which you will add your C solution and comments. The starting point code includes one helper function:
    • get_filename_from_commandline: takes the storage space for a string and the command line arguments and initializes the string storage space with the filename from the command line argument. You should not change this function, but feel free to change where it gets called in your program.

  4. floats.txt, floats2.txt, floats3.txt, and floatsbig.txt: example input files to your program. These are provided for your convenience to help you test your program. You will likely want to create other test files to more extensively test your program before you consider it finished.

To compile your program, run make, which will use the Makefile to build your program (and link in the provided readfile library). Running make will show you the compiler output, which you should examine for errors and warnings. There is one unused variable warning with the starting point code that will go away when you write code that uses this variable.

  $ make
  gcc -g -Wall -Wvla -Werror -Wno-error=unused-variable -c readfile.c
  gcc -g -Wall -Wvla -Werror -Wno-error=unused-variable -o sorter sorter.c  readfile.o
  sorter.c: In function 'main':
  sorter.c:30:9: warning: unused variable 'values' [-Wunused-variable]
   float values[ARRAYSIZE];

Program Start-up

Your program will take one command line argument: the name of the input file containing floating point values to sort, one on each line. It should read values from the file (using the provided library), print the unsorted values, sort them, and print out the sorted result back to the user. Here is an example of how you invoke the program:

  $ ./sorter floats.txt        

File Format

The input file format consists of several lines of an ASCII text file. A properly formatted file will contain a short header, consisting of a single line with one integer and two floats on it. These numbers represent the total number of floats in the file (i.e., the number of subsequent lines), as well as the minimum and maximum to-be-sorted float value in the file. These numbers will be written like this:

For example, here is the header of a valid input file:

  4 0.0 9.0

This header indicates that the file contains a total of 4 floats that need to be sorted. The smallest float value in the file will be 0.0, and the largest will be 9.0. You may not need to know the minimum and maximum values to successfully sort the values, but you will need to inform the user about the range of values being sorted.

Included with the starting point code are a few sample test files you can use to test your code. Every line after the first line in the file will contain a single floating point number. These are the float values that must be sorted. For example, a file containing the header we just saw might look like this (after the first line):

  0.0
  2.1
  9.0
  5.3

File I/O

For this assignment we'll use functions from the provided readfile library (in the files readfile.c and readfile.h). You should not change any code in these files. The readfile.h file contains function prototypes for the readfile library. There are function comments in this file that describe each function and a high-level comment that describes how to use the library.

Here are the general rules for how to use these functions:

  1. Open a file by calling: open_file(), passing in the name of the file to open as a string. The return value of open_file() tells you whether or not the file was opened successfully. It returns 0 if the file is successfully opened, and -1 if the file cannot be opened. You should always check the return value of this function and respond appropriately!

  2. Call the read_int(), read_string(), read_float() functions to read values from the file into your program's variables, where the name of the function you call determines the resulting type of the return value. Like open_file(), these functions return 0 on success, and you should always check their return value. If you've reached the end of the file, they will return -1.

    These functions take arguments much like scanf does: they need to know the memory location of where to put the value read in.

    For example:

      int x;
      float f;
      char s[20];
      ...
      /* These functions return 0 on success or -1 if read fails or
       * if there is nothing left to read (end-of-file has been reached). */
      ret = read_float(&f); 
      ret = read_int(&x)
      ret = read_string(s)
    

  3. Close the file when you're done with it: close_file().

If you are curious, the implementation of these functions is in readfile.c. You can take a look and see how it uses the C FILE * interface and fscanf functions for reading. We will use this interface directly later in the semester. For now, we're hiding it under a layer of abstraction.

Requirements

Your program's output should look like this: output from an example run. It doesn't show every possible run or error handling, but should give you some idea of what a correct program will look like. To make my job of grading easier, please make your output match the example as closely as possible.

For full credit, your solution should meet the following requirements:

Implementation Recommendations

The following is the suggested way to implement the lab and fulfill the requirements. If you intend to significantly deviate from this design, please let me know so that I can do a basic sanity check of your proposed changes.

Tips

Lab Questionnaire
With every lab assignment is a file named QUESTIONNAIRE for you to fill out (with vim or another Unix editor) and submit with your lab solution. In this file you will answer some questions about the lab assignment. You should fill this out and submit it with your lab solution.

Submit

Before the Due Date

Only one of you or your partner needs to push your solution from one of your local repos to the GitHub remote repo. (It doesn't hurt if you both push, but the last pushed version before the due date is the one we will grade, so be careful that you are pushing the version you want to submit for grading):

From one of your local repos (in your ~you/cs31/labs/Lab2-partner1-partner2 subdirectory)

git push

Troubleshooting

If git push fails, then there are likely local changes you haven't committed. Commit those first, then try pushing again:
git add sorter.c
git add QUESTIONNAIRE
git commit
git push
Another likely source of a failed push is that your partner pushed, and you have not pulled their changes. Do a git pull. Compile and test that your code still works. Then you can add, commit, and push.

If that doesn't work, take a look at the "Troubleshooting" section of the Using git page. You may need to pull and merge some changes from master into your local. If so, this indicates that your partner pushed changes that you have not yet merged into your local. Anytime you pull into your local, you need to check that your code still works before submitting.