Starting point

Right click and save this source code file.

Right click and save this database file.

Then, upload both to your AFS space through FTP. Put them in the same directory!

Compiling and running

Just like before, on thoth:

gcc -Wall -Werror --std=c99 -o lab3 lab3.c

If you run ./lab3 now, it will print out directions on how to use it. This is called usage info and most command-line programs will print something like this.

Your goal

food.db is a binary file. Its format is very simple: it is an array of Food structs. (Look at the top of lab3.c for that struct.) You can try running hexdump -C food.db to see the contents of the file.

Your program will let you view the contents of food.db and add new items to the end.

Although simple, it will show you the basics of using binary files, seeking around, parsing command-line arguments, and giving good error messages.

I have already given you some code to check which command-line arguments were passed, and you have to write all the interesting bits.

Your program will be able to:

  1. Print all the foods in the file, by using ./lab3 print.

     $ ./lab3 print
     There are 6 foods in the database.
     Food #0: grapes ($2.99 each, 10 in stock)
     Food #1: bananas ($0.49 each, 300 in stock)
     Food #2: apples ($1.99 each, 45 in stock)
     Food #3: bread ($2.49 each, 200 in stock)
     Food #4: juice ($1.00 each, 40 in stock)
     Food #5: egg ($0.89 each, 400 in stock)
    
  2. Print just one food, by using ./lab3 print n, where n is the index of the food to print:

     $ ./lab3 print 3
     Food #3: bread ($2.49 each, 200 in stock)
    
  3. Add a new food, by using ./lab3 add name price stock.

     $ ./lab3 add milk 3.45 2000
     $ ./lab3 print
     There are 7 foods in the database.
     Food #0: grapes ($2.99 each, 10 in stock)
     Food #1: bananas ($0.49 each, 300 in stock)
     Food #2: apples ($1.99 each, 45 in stock)
     Food #3: bread ($2.49 each, 200 in stock)
     Food #4: juice ($1.00 each, 40 in stock)
     Food #5: egg ($0.89 each, 400 in stock)
     Food #6: milk ($3.45 each, 2000 in stock)
    
  4. Give the user good errors when they give invalid inputs:

     $ ./lab3 print 2049
     Invalid index!
     $ ./lab3 print -1
     Invalid index!
     $ ./lab3 add thisnameiswaytoolong 0 -1
     Name is too long!
     $ ./lab3 add pineapple 0 -1
     Price must be at least $0.01!
     $ ./lab3 add pineapple 4 -1
     Stock must be at least 0!
    

What to do

Implement the code in lab3.c.

Follow the directions in the comments, and remove the comments as you go.

Do not try to do everything first, and then try to compile and run. Implement one function, then compile, then test. Repeat.

  1. To implement ./lab3 print:
    1. implement open_database
      • compile, and test. make sure db is not NULL in main.
    2. implement count_foods
      • once that’s implemented, ./lab3 print should show this with the default database:

          $ ./lab3 print
          There are 6 foods in the database.
        
    3. implement read_food
      • this file is basically an array of Food, so you will have to calculate the position…
      • make sure you get the order of parameters to fseek right. I screwed it up when I made this. :P
    4. implement the code inside the first if in main.
      • it’s just a loop. veeery simple.
      • test, test, test.
  2. then work on ./lab3 print n:
    • this is the second if in main.
    • you’ve used sscanf before.
    • what is the valid range for the index?
    • you already have read_food and print_food. don’t reimplement them.
  3. finally, work on ./lab3 add:
    • it has the most steps, but it’s not really any more complex.
    • you can sscanf directly into the struct variable’s fields:
        sscanf(argv[4], "%d", &newFood.stock);
      
    • I told you strcpy was bad and evil. Well, it is, but you are doing an explicit check before using it, so it will be safe.
    • the valid range for price is price >= 0.01.
    • the valid range for stock is stock >= 0.
    • you’ll implement add_food along the way. it’s only a couple lines.

Submission

Just like before. Follow those, but replace lab1 with lab3.