Week 6 Laboratory — Structured Data Types

Note:

As usual, you can use dry run:

prompt$ ~cs1921/bin/dryrun lab06

prompt$ ~cs1921/bin/dryrun lab06 2

Exercises

  1. (Structs) Write a program called philatelic.c that records and prints the personal details of 2 fictional members of the philatelic club as specified in the tutorial exercises. (The personal details of the members may be hard-coded into the program.) A sample output of the program is the following:

    Name: Samuel Simon
          Phone: 9999999
          Address: 20 Smith Street, Sydney
    Name: Louise Lion
          Phone: 9888888
          Address: 81 Lyon Lane, Lismore
    

    While the personal details may be different, you should match the above format exactly.

  2. (Structs) A file called database.txt stores all the user information for a top secret database. Each line of the database corresponds to a single person and is of the following format

    lastname firstname year_of_birth password securityClearanceLevel secret
    

    Note: the fields in the database are separated by spaces

    There are only 3 possible values for securityClearanceLevel, namely, none, high and top. For example, the first few lines of the database.txt file may look like this

    Dracula Martin 1285 i_am_undead top is actually a vampire
    Gregorius Abdul 1953 password123 high has broken his leg while tap dancing
    Pham Fei 1985 wordpass098 none second cousin of chuck norris
    

    Your task is to write a program, security.c, which reads in the data from this database.txt file and stores it in an appropriate way, using structs and enums. You are then to ask the user for a username and password. A username is simply a person's first name and last name concatenated together, eg Martin Dracula will have the username "MartinDracula". If the user enters a valid username and password, you are to print out correct username + password entered as well as the first name and secret of every person in the database with a lower security clearance. If the user enters an invalid username and password combination, you are to print out the message "you did not enter a correct username/password combination".

    A sample run of the program would look like this:
    $ gcc -Wall -Werror -o security security.c
    $ ./security
    username: MartinDracula
    password: i_am_undead
    correct username + password entered
    Abdul's secret is 'has broken his leg while tap dancing'
    Fei's secret is 'second cousin of chuck norris'
    $ ./security
    username: AbdulGregorius
    password: wrongpassword
    you did not enter a correct username/password combination
    

    Assumptions:

    You may use the following skeleton to get started:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define DATABASE_FILE "database.txt"
    #define DATABASE_DELIMITER ','
    #define MAX_LINE_LENGTH 100
    #define MAX_DATABASE_LENGTH 1000
    #define TRUE 1
    #define FALSE 0
    
    void chomp(char *string);
    
    typedef struct {
       char *firstName;
       char *lastName;
       // TODO add something for clearance level here perhaps?
       int age;
       char *password;
       char *secret;
    } person;
    
    int main(int argc, char *argv[]) {
       int retval = EXIT_SUCCESS;
    
       // open database file
       FILE *file = fopen(DATABASE_FILE, "r");
       if (file == NULL) {
          fprintf(stderr, "could not open file");
          retval = EXIT_FAILURE;
       } else {
          person people[MAX_DATABASE_LENGTH];
          int count = 0;
          char firstName[MAX_LINE_LENGTH];
          char lastName[MAX_LINE_LENGTH];
          int age;
          char clearance[MAX_LINE_LENGTH];
          char password[MAX_LINE_LENGTH];
          char secret[MAX_LINE_LENGTH];
    
          // read entire database into the people array
          while (fscanf(file,"%s %s %d %s %s ", lastName, firstName, &age, password, clearance) != EOF) {
             if (fgets(secret, MAX_LINE_LENGTH, file) != NULL) {
                // lastname
                people[count].lastName = (char *)malloc(sizeof(char) * strlen(lastName) + 1);
                strcpy(people[count].lastName, lastName);
                // firstname
                people[count].firstName = (char *)malloc(sizeof(char) * strlen(firstName) + 1);
                strcpy(people[count].firstName, firstName);
                // age
                people[count].age = age;
                // clearance
                //////////////////////////////////////////
                // TODO you need to write some code here//
                //////////////////////////////////////////
                // password
                people[count].password = (char *)malloc(sizeof(char) * strlen(password) + 1);
                strcpy(people[count].password, password);
                // secret
                chomp(secret);
                people[count].secret = (char *)malloc(sizeof(char) * strlen(secret) + 1);
                strcpy(people[count].secret, secret);
                count++;
             } else {
                fprintf(stderr, "error reading file\n");
                retval = EXIT_FAILURE;
             }
          }
          fclose(file);
    
          //////////////////////////////////////////
          // TODO you need to write some code here//
          //////////////////////////////////////////
       }
       return retval;
    }
    
    // removes the newline, if it exists
    void chomp(char *string) {
       if (string[strlen(string) - 1] == '\n') {
          string[strlen(string) - 1] = '\0';
       }
    }
    

  3. (Structs + malloc) Write a program called colours.c that reads a sequence of people's names and integers from stdin into an array of structs. The array must be dynamic (and hence may not be fixed length). A struct here has the form:

    #define NAMLEN 50
    typedef struct {
       char name[NAMLEN];
       int  colour;
    } Preferences;
    

    After reading all the data, your program should output the information stored in the array as shown below, where the numbers actually correspond to colours:
    0=cyan, 1=pink, 2=green, 3=red, 4=yellow, 5=blue, 6=unknown
    

    You may use the following test data:

    20
    Xiang 5
    Bin 1
    Navid 0
    Abdul 1
    Ming-Tak 5
    Surya 2
    Jingxu 3
    Lasit 2
    Yi 4
    Ghit-Hong 6
    John 3
    Nam-Thanh 3
    Jian 0
    Kuninda 1
    Wenxi 6
    Wenfei 4
    Fei 1
    Xiaotian 0
    Ke 2
    Ge 6
    

    Notice that the first line of this data indicates the number of people. The output for this test data should be:

    Xiang likes blue
    Bin likes pink
    Navid likes cyan
    Abdul likes pink
    Ming-Tak likes blue
    Surya likes green
    Jingxu likes red
    Lasit likes green
    Yi likes yellow
    Ghit-Hong likes unknown
    John likes red
    Nam-Thanh likes red
    Jian likes cyan
    Kuninda likes pink
    Wenxi likes unknown
    Wenfei likes yellow
    Fei likes pink
    Xiaotian likes cyan
    Ke likes green
    Ge likes unknown
    

    Note:

  4. (Feedback) Have a brief conversation with your tutor about your performance in the course so far.

Submit your work (not before your scheduled lab please) using:


  give  cs1921  lab06  philatelic.c  security.c  colours.c