This week's lab covers FILE I/O, sorting and structures.
Practice File I/O
Learn how to sort an array of structure data type
Lecture 22 and 23 on structures
Lecture 24 on FILE I/O
Manual page for standard library string functions
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;
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 */
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 */
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 */
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;
}
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);
}
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(____________);
}
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.
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:
"lab13.c", the source file that you have to edit;
"album" and "quantities", text files from which your program will take its input;
"lab13demo", an executable that you can run to see how you program is supposed to work.
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.
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.
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] .
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.
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(______________________,
_____________________, ______________________,
_____________________);
Complete the code for the compareQuantityAsc function. Answer question #2 on the answer sheet.
When you are done, compile and run your code like in the already very familiar way.
That's all folks!