CS101 - LAB ACTIVITY 12

This  lab has just two parts.


Objectives




References

Lecture 19 through 24

MP2 instructions


Part 1: Prelab



You should use the material found in Lecture 19&20 and 21 of the course notes. As with all prelabs/labs, if you are not sure of the answer you may go to any EWS lab on campus and check your results by using the gcc compiler, or you can ask anyone of the CS101 staff for help.

1.      Write the code to create a structure definition for Student, a structure with two fields (members) , the first called netid (integer data type) and the second called name (char array of size 64). Use typedef to name the structure type Student.

______________________________


______________________________


______________________________


______________________________

Define your structure in such a way that you can declare a structure variable of type Student as follows:


Student x;


2.      Now suppose we declare an array of Student structures as follows:


Student students[10];


Remember array indexing begins with 0 in C.

(a) Write a single line of C code to assign the name "Michael Jordan" to the name member(field) of the fifth element of the array students. Hint: use the strcpy function.

________________________________________________________

(b) Write a single line of C code to assign the value of the name member(field) in the fifth element of the students array to the name member(field) of ninth element of the students array.

________________________________________________________

(c) Write a single line of code to give the second element of the students array the same values as the last element of students array.

________________________________________________________


3.      Using the student datatype you created in the first question, declare a single variable named stu of datatype student. On the same line that you declare your variable assign "Kobe Bryant" to the name member(field) and 25 to the netid member(field).


_______________________________________________________________________________



4.      In this problem, you are going to use functions from math library. If you test your code by typing into a file named q4.c then to compile the code you would type,

gcc q4.c -lm

where -lm (dash L m ) means, link to the math library.

Complete the code for the function named convert that converts points in Polar coordinates to points in Cartesian coordinates by means of the formula,

x = radius * cos(theta)
y = radius * sin(theta)

A point in the plane can be uniquely identified by the pair (radius, theta) where radius is the distance of the point from the origin and theta is the angle formed between the two lines, the x-axis and the line between the origin and the point. We can compute the (x,y) coordinate by using the above formulas.

#include <stdio.h>
#include <math.h>

typedef struct
{
      double x;
      double y;
} cartesian;

typedef struct
{
     double radius;
     double theta;
} polar;

cartesian convert( polar point)
{

    cartesian p;

    ___________________________________

    ___________________________________

    return p;
}

void main(void)
{
    polar point = { 1.0 , 3.141592653589793 / 4 };
    cartesian p;
    p = convert(point);
    printf(" x = %lf , y = %lf \n", p.x , p.y);
}

When your code is run you should obtain the output shown below.


x = .707107 y = .707107

5.      (Questions 5 and 6 use the following datatype named Employee). Fill in the code needed to initialize the variable named john with the information provided in myName,myNetid, and soc.
Note that the datatype of the variable tom is Employee.


#include <stdio.h>
#include <string.h>

typedef struct
{
   char name[20];
   int ssn;
   char netid[20];
} Employee;

void printEmployee(Employee);

void main(void)
{
   char myName[] = "John Smith";
   char myNetid[] = "johnsmith";
   int soc = 987654321;
   Employee john;


   strcpy( ____________________________________, myName);


   strcpy( ____________________________________, myNetid);


   _____________________________________ = soc;

   printEmployee(john);
}

6.      Fill in the code for the printEmployee function.

void printEmployee(Employee e)
{
   printf("Name: ");
   printf(_______________, _______________________); /* Print the name */
   printf("\n");


   printf("Netid: ");
   printf(_______________, _______________________); /* Print the netid */
   printf("\n");


   printf("SSN: ");
   printf(_______________, ________________________); /* Print the SSN */
   printf("\n");
}

7.      One problem with %s is that we cannot read more than one word at a time since the space character serves as a delimiter. To fix this problem (only for reading strings) we will use the brackets conversion specifier %[ ], consult page 498 of Applied C for more information.
Inside the brackets we will use the special symbol '^' meaning NOT. For example, %[^;]; then the [^ ; ] part means read all characters (including blanks) while the character is NOT ; (and therefore stop reading when the next character is a ; ) and the ; outside the [^ ;]; means read and discard the next ;. For example, if we declared,

char artist[40];
char song_name[40];
char album_title[40];
int track_length;

Assume that the standard input (from the keyboard) contains:

The Beatles; 214

Then

 scanf(" %[^;]; %i", artist, &track_length);

reads "The Beatles" into the array 'artist' and the number 214 into 'track_length'.

Complete the following C program to read in

 The Beatles; The Long and Winding Road; Let It Be... Naked; 214

into 'artist', 'song_name', 'album_title' and 'track_length'


#include <stdio.h>

void main(void)
{
char artist[40];

char song_name[40];
char album_title[40];
int track_length;

printf(" Please enter the artist, song_name, album_title, and track_length\n");

scanf(" %[^;]; %________ %_________ %i",artist, ______________, ________________, _______________);

printf(" %s \n %s \n %s \n %i\n",artist,song_name, album_title,track_length);
}






Part 2: Lab


In this lab, you will be writing the readAlbums and mainMenu functions of your MP2. Since this is part of your MP, you should work this lab individually.

Follow the instructions for MP2 under the heading "Preparation" to get ready to do the MP .

Also, read the brief introduction and familiarize yourself with the structure definition of an Album.

mainMenu function

The first thing we'll do is write the mainMenu function. In gedit if you open the file mp2.h you will find the prototype:

int mainMenu( void );

Copy and paste this prototype into the input.c file. DO NOT modify the mp2.h file. In input.c modify this prototype by replacing the semicolon with opening and closing curly braces. Then your input.c file should look like the following:

/* input.c */
#include "mp2.h"
#include "user.h"
int readAlbums( char *filename, Album albums[], int size, int capacity )
{
}
int mainMenu( void )
{
}

Don't forget to remove the semicolon from the end of the line after you copy it over, and to put the code for your function in curly braces ( "{" and "}" ).
You've done menu functions in previous labs; this one will be very similar. You want to display the list of options to the user, and return whatever number the user enters. Assume that the user always enters an integer. We won't worry about checking for invalid integer values in the mainMenu function. You will need to declare an integer variable.

Your menu function should display the following menu:

    Main Menu
    1. Display
    2. Sort
    3. Search
    4. Edit
    5. Statistics
    6. Save to disk
    0. Exit
    Please enter the choice: 

Next use the scanf function to read the value the user entered at the keyboard. Finally, return the choice to the function that called mainMenu.

Every function you write for this MP2 will be done in this way. That is, first copy and paste the prototype found in mp2.h See the Implementation section for a step by step list of functions. You will only be writing the code for mainMenu and readAlbums for this lab 12.

When you finish writing your code for the menu function don't forget to save your changes and make your project as described in the MP2 instructions.

readAlbums Function

Of course, your CD album program isn't going to be much use unless it can read a file containing information concerning CD albums. That's what the readAlbums function does.

The function header for readAlbums has already been typed into the input.c file for you:

int readAlbums( char *filename, Album albums[], int size, int capacity)
{
}

The function readAlbums is called by main. If you look at the main function in mp2.c, a line of code that calls readAlbums with the correct parameters (the filename, the array of Albums and 0 is the current number of albums and MAX_ALBUMS will be assigned to capacity) has been included.

Since you're going to get input from the user (keyboard by using mainMenu) as well as from the file (album.dat by readAlbums), we'll have to use real file I/O (input/output) here, rather than just reading from "standard in" (the keyboard) and letting the operating system make us think the file was the keyboard (that's what you've been doing when you run something like "program < file"). Since we haven't seen that yet, here's how it should be done:

Fill in the blanks on the answer sheet for questions 1, 2, and 3 in Part 2 and you're done! 
 /* begin of readAlbums */
        
        int track, i; 
        FILE * fileptr;  /* flieptr is a pointer variable, FILE is a new datatype */
        
        fileptr = fopen( filename, "r"); /* filename is a string, "r" means open file for reading */
        if (fileptr == NULL)
                return -1;
                
        /* read the data from ALBUM_FILE */
        /* first record looks like ... 
                1001; One Heart; Celine Dion; 2003; 14; 2; 13.99 
                211.10 96.15 67.93 340.67 138.01 250.97 259.76 74.66 114.92 268.26 126.47 79.63
        */
        
        /* The datatype Album (from mp2.h) looks like...        
        typedef struct {
                int     cdno;      
                char    title[30]; 
                char    artist[20]; 
                int     year;
                int     num_tracks; 
                int     quantity;
                float   price;
                float   sales[MONTHS];  cd sales ($US) over the 12 months in 2005 
        
                Track   tracks[20]; 
        } Album;        
        */
        
        /* check to make sure that we haven't exceeded the maximum size for the array albums */
        if ( size >= capacity) {
                        fclose(fileptr);
                        return size;
                }
        /* you must fill in the blank on the line below */
        /* size starts at 0 */
        while( EOF != fscanf(fileptr, "__________________________________", 
                &albums[size].cdno,
                 albums[size].title,
                 albums[size].artist,
                &albums[size].year,
                &albums[size].num_tracks,
                &albums[size].quantity,
                &albums[size].price) ) {
                
                /* read the sales over 12 months */
                for ( i = 0; i < MONTHS; i ++ ) {
                        fscanf( fileptr, " %f", &albums[size].sales[i]);
                }
                
                /* We need to read the track data into the array named tracks. 
                 * The first record  has the following form ...
                 *    I Drove All Night; 240
                 */
                /* The datatype Track (from mp2.h) looks like...
                        typedef struct {
                                char    name[40];    track name or song name 
                                int     length;      in seconds 
                        } Track;
                */
                for( track = 0; track < albums[size].num_tracks; ++track ) {
                        /* fill in the following blanks to read in all the track data */
                        fscanf( __________ ," %[^;]; %i ", albums[size].tracks[track].name, ___________________________________________ );
                }
                
                /* we succeeded in reading in one more album so increase size by one */
                size++;
                 /* we don't want to read more CDs than the size of the albums array so check now */
                
                if ( size >= capacity) {
                        fclose(fileptr);
                        return size;
                }
        } /* end of while */
        
        fclose(fileptr);
        return size;
/* end of readAlbums */

Notice that there is a "space" before %[^;] in the format string of fscanf. This is critical to ignore any blank space in the input file before your program sees the track name. When you test your program, it's going to be a little hard to tell if readAlbums is working if you can't see what you read in, right? Fortunately, the mp2 checker provided will allow you to test your readAlbums function without having to write the main function. (See below.)

Prepare for your MP2

In this lab, you have written the function mainMenu and readAlbums. In MP2, you are asked to write a bunch of other functions. To get prepared, please read instructions for MP2, "Before you start..". As the last part of this lab, please copy and paste each function prototype into their corresponding .c file. DO NOT modify the mp2.h file. Modify each function so that they have an empty function body, just like what you did for mainMenu and readAlbums at the very beginning of this lab.

If you do it right, you should be able to compile every .c files by typing:

make mp2checker
from the ~/mp2 directory.

If you see any errors, correct any mistakes (e.g., missing a pair of curly brackets, forgetting remove the semicolon after the parenthesis).

Now, you can play with the mp2checker. Please refer to the section "Checking" in the instructions for MP2.