CS101 - LAB ACTIVITY 13

This week's lab covers FILE I/O, sorting and structures.


Objectives


References


Part 1: Prelab

Part A: Structures

Use the following structures named Album and Track along with the variable named mycd in the next 3 questions.

typedef struct {
        char    name[40];   /* track name or song name */
        int     length;     /* in seconds */
} Track;

typedef struct { int cdno; /* cd number */ char title[30]; char artist[20]; int year; int num_tracks; /* number of tracks */ int quantity; float price; float sales[MONTHS]; /* cd sales ($US) over the 12 months in 2005 */ Track tracks[20]; /* info for each track */ } Album;
Album mycd;
  1. Given the structures and variable declared above, complete the C code below by filling in the blanks to assign to the variable mycd the following values: cdno = 100 , title = "Holding Onto Strings Better Left to Fray", sales for January = 2000.00 . Hint: use strcpy to assign strings.


    _________________________________________ /* assign 100 to the cdno field of the variable named mycd */


    _________________________________________ /* assign "Holding Onto Strings Better Left to Fray" to the title field */


    _________________________________________ /* assign 2000.00 to the first element of the sales array */



  2. Continuing from question 1, complete the C code below by filling in the blanks to assign to the variable mycd the following values: for the 14th track, name = "Country Song", length = 349. Hint: indexing in arrays start with 0.

    _____________________________________ /* assign "Country Song" to the name field of the 14th track of the variable named mycd */


    _____________________________________ /* assign 349 to the length field of the track */

  3. Given the structures defined before question 1, and given the declarations below, use the "*" and "->" operators to complete the assignment of the quantity = 2 to the variable named mycd .

    Album * ptr = & mycd;  /* ptr , points to mycd */


    however we don't want you to write your answer as,

     mycd.quantity = 2;


    we want you to use the variable ptr and the "*" operator to assign 2 to the quantity field of the variable mycd and then do the same assignment again but this time using the "->" operator .
    (see lect21&22 slides 30-32)

    _____________________________  = 2;  /* assign 2 to the quantity field of mycd, use the * operator */
      
    ______________________________ = 2;  /* again, assign 2 to the quantity field of mycd,use the -> operator */
  4. Given the declarations below, complete the C code by filling in the blanks with the correct answers.

        #include <stdio.h>
        typedef struct 
        {
          double real;
          double imaginary;
        } complex;

complex add(complex,complex); /* prototype */
void main(void) { complex x = {1.0,2.0}, y , z;

 z = x; /* assigns all values of fields of x to z */ y = add(x,z); /* perform the "complex" addition of x and z and assign to y */ printf(" real(y) = %lf, imag(y) = %lf \n", _______________________, _____________________________); }
/* to add two complex numbers use the rule {real1,imaginary1} + {real2,imaginary2} = {real1+real2, imaginary1+imaginary2} */ /* so {1.0,2.0} + {1.0,2.0} = {2.0,4.0} */
complex add(complex a , complex b) { /* declare c and initialize */ /* c is initialized with the sum of a and b */

 complex c = {______________________________________________ , __________________________________________________________}; return c; }

Part B: qsort

  1. Fill in the blanks below to complete the code for the function compare_mag that qsort will call to sort an array of complex numbers (see question #4) in ascending order by magnitude. If we define the variable
    complex y = {3.0, 4.0};
    then the magnitdue of y equals sqrt(y.real*y.real + y.imaginary * y.imaginary) (which is 5.0 in this example).

    #include  <stdio.h>
    #include  <stdlib.h>
    #include  <math.h>
        
    typedef struct 
    {
      double real;
      double imaginary;
    } complex;

    int compare_mag( complex * ptr1, complex * ptr2) { double mag1 = sqrt( ____________________________ + ________________________________ ); double mag2 = sqrt( ____________________________ + ________________________________ );
    if ( mag1 > mag2 ) return 1; else if ( ___________________________________ < ______________________________________) return -1; else return 0; }

    void main(void) { int i; complex arr[] = {{2.0, 0.0}, {3.0,4.0}, {0.0, 3.0}, {6.0 , 8.0}} ; qsort(arr, 4 , sizeof(arr[0]), compare_mag); for(i=0; i< 4 ; ++i) printf(" %lf, %lf \n", arr[i].real,arr[i].imaginary); }

Part C: FileI/O

  1. Fill in the blanks to complete the following piece of code. This piece of code opens a file, reads pairs of strings into structs, and then closes the file. The file you are using is named "input.dat", is in the current directory, and contains pairs of first and last names and total points separated by spaces. The names are listed with the last name first, and the first name second. Therefore we can use %s when we use fscanf since we will assume that first names (and last names) don't contain blanks. The first few lines of the file will look like this:

        McKellan Ian 565
        Wood Elijah 692
        Tyler Liv 483
        Blanchett Cate 615

        Assume you have all the necessary header files included, and the following structure is defined:

   #include <stdio.h>

    typedef struct
    {
        char first[30];
        char last[30];
        int total_points;
    } student;

        /* You may also assume that all names are less than 30 characters long and that the file contains at most 30 pairs of names. */

        void main(void)
        {
            int i=0, k;

            /* Declare a variable called 'class' that is an array of 30 student(s): */

            student class[30];

            _______________________________________________ /* Declare a variable 'pt' that is a pointer to FILE */



            pt = ___________________________________________________________________/* Use fopen to open the file "input.dat" for reading */


            if (pt == NULL)

                printf("file not opened for reading!\n"); /* Read in all names from the the input file */



            while(EOF != fscanf(______________ , "%s %s %i\n", class[i].last, class[i].first , &class[i].total_points ))
            {
                i++;
            }

   	    for(k=0; k < i; ++k)
   		printf(" %s %s %i \n", class[k].last, class[k].first, class[k].total_points);

            /* Close the file */


        fclose(____________);
}


Part 2: Reading albums from multiple files and sorting albums

1. Requirements Specification (Problem Definition)

In this lab you will do a mini mp2. We provide you with two files.

Each row of data in the file named "albums" has the following format:

    cdno; Title With Spaces; price

The file named "quantities" has the following format:

    cdno; quantity

Since the typical music store buys and sells albums frequently, it is sometimes convenient to store the quantity of an album that is in stock in a separate file from the rest of the information about the album. It would be nice to allow the quantities to appear in a file in any order. We will assume that the albums in the album file are not necessarily in the same order as the quantities in the quantities file.

We will complete a program to read data from the "albums" file, without quantities, and then to read the "quantities" file and add the quantities for the matching album by matching by cdno. Finally, the program will sort the albums in ascending order of quantity.

2. Analysis---Refine, Generalize, Decompose the problem definition

To save you time, we have provided the skeleton of the program in the file named lab13.c First, copy file named lab13.tar.gz into your home directory. To do this type the following commands at the Unix prompt:

cd

cp ~cs101ta/public_html/labs/lab13/lab13.tar.gz .

tar -xzf lab13.tar.gz you can copy/paste this command to make sure you execute this command EXACTLY as stated.

At the Unix prompt type,

cd ~/lab13

ls

Inside the lab13 directory you will see the following files:

To run "lab13demo" from the Unix prompt type
lab13demo



Use gedit to open the file "lab13.c" in your editor.
Notice that the data type Album is simpler than what we use in MP 2.

3. Design---Develop Algorithm

Step 1

Use the fopen function to open the two files "albums" and "quantities" in read mode "r". Note that the pointers named "albumsFileptr" and "quantitiesFileptr" will hold the address values that the fopen function returns. You will need to call fopen twice.

We have written code that checks whether the files named "albums" and "quantities" were successfully opened in read mode. If not then the program will exit after displaying an appropriate message.

Step 2

Next you should complete the code in the loop below to read all the data from the "albums" file.

 count = 0;
while (EOF != fscanf(albumsFileptr," %i; %[^;]; %f", /* Step 2: complete the code here */ ))
{
count++; /* count keeps track of how many albums have been read */
if (count >= MAX_ALBUMS) /* we can't handle more than 20 albums in our mini mp */
{
fclose(albumsFileptr);
fclose(quantitiesFileptr);
printf("Error: Too many albums read.\n\n");
return;
}
}

Note that you are trying to read values into the array named "albums". You can use the variable named "count" to index into this array, like albums[count] .

Step 3

The code to read the lines from the quantity file is already written. But the cdno and quantity are read to temporary variables cdno and quantity. Write a for loop from count = 0 to count < num_albums and check if albums[count].cdno equals cdno. If you find a match then assign quantity to albums[count].quantity.



Step 4

Complete the code to sort the albums by quantity in ascending order. The name of the function that qsort calls to sort the albums in ascending order by quantity is called compareQuantityAsc. Answer Question #1 on the answer sheet.


qsort(______________________, _____________________, ______________________, _____________________);

Step 5

Complete the code for the compareQuantityAsc function. Answer question #2 on the answer sheet.



Compiling and Running

When you are done, compile and run your code like in the already very familiar way.



That's all folks!