The University of Western Australia
CITS2002 Systems Programming
 

Department of Computer Science and Software Engineering

CITS2002 Systems Programming

Solutions for Labsheet 2 - for the week commencing 12th August 2019

This page provides some sample solutions and discussion on some of the tasks of Labsheet-2.

Exercises

  1. A year is a leap year if it is divisible by 400, or if it is divisible by 4 and not divisible by 100. For example - 1996, 2000, and 2012 were leap years, while 1899, 1900, and 2013 were not. Write a program that determines if the year, supplied as a command-line argument, is a leap year or not.

Any challenge in this question is addressed by using additional parentheses to make your solution readable. There is no penalty for using an "excessive" number of parentheses, and (after correctness) readability of your code is the most important issue.

// (a multiple of 400) OR ((a multiple of 4) AND (NOT a multiple of 100)) 
if((year%400 == 0) || (((year%4 == 0) && (year%100 != 0))) {
    printf("YES\n");
}
else {
    printf("NO\n");
}

  1. Write a program which accepts exactly 3 command-line arguments, converts each to an integer value, and prints the maximum of the 3 values.

The solution to this exercise forms a very standard "pattern" of writing our introductory programs - the main() function should check the number of command-line arguments; if incorrect, a helpful error message should be printed, and the program should exit indicating failure; otherwise, the rest of rest of main() processes the command-line arguments.

This program's command-line arguments are strings of characters, and each needs to be converted to an integer value using the standard atoi() function. We first assume that the first value is the maximum value, and then check to see if the second, and then the third, are greater. Note how we've had to use a fixed number of if tests to find the maximum of all values:

#include <stdio.h>
#include <stdlib.h>

int main(int argcount, char *argvalue[])
{
//  CHECK THE NUMBER OF COMMAND-LINE ARGUMENTS
    if(argcount != 4) {
        fprintf(stderr, "Usage: %s value1 value2 value3\n", argvalue[0]);
        exit(EXIT_FAILURE);             // Exit indicating failure
    }

//  CORRECT NUMBER OF COMMAND-LINE ARGUMENTS, PROCESS THEIR VALUES
    else {
//  CONVERT EACH COMMAND-LINE ARGUMENT TO AN INTEGER VALUE
        int value1  =  atoi(argvalue[1]);
        int value2  =  atoi(argvalue[2]);
        int value3  =  atoi(argvalue[3]);

//  ASSUME THAT THE FIRST ARGUMENT PROVIDES THE MAXIMUM VALUE
        int maximum = value1;

//  COMPARE OUR ASSUMED MAXIMUM AGAINST THE OTHER TWO VALUES
        if(maximum < value2) {
            maximum = value2;
        }
        if(maximum < value3) {
            maximum = value3;
        }
//  PRINT THE MAXIMUM VALUE FOUND
        printf("maximum is %i\n", maximum);
        exit(EXIT_SUCCESS);             // Exit indicating success
    }
    return 0;
}

  1. Rewrite your solution to the previous exercise so that it now prints the maximum of an arbitrary number of command-line arguments, perhaps 3, or 10, or 50....

In this question we do not require a fixed number of command-line arguments, just at least one. We again assume that the first command-line argument (its integer value) provides the maximum value, and then loop over all remaining values looking for a new maximum:

    ....
//  CHECK THE NUMBER OF COMMAND-LINE ARGUMENTS
    if(argcount < 2) {
        fprintf(stderr, "Usage: %s value1 [value2 ...]\n", argvalue[0]);
        exit(EXIT_FAILURE);             // Exit indicating failure
    }
    else {
//  ASSUME THAT THE FIRST ARGUMENT PROVIDES THE MAXIMUM VALUE
        int maximum = atoi(argvalue[1]);

//  LOOP OVER ANY REMAINING ARGUMENTS (THERE MAY BE NONE!)
        for(int a = 2 ; a < argcount ; a = a + 1) {
            int thisvalue = atoi(argvalue[a]);
        
//  COMPARE OUR ASSUMED MAXIMUM AGAINST ANY OTHER VALUES
            if(maximum < thisvalue) {
                maximum = thisvalue;
            }
        }
//  PRINT THE MAXIMUM VALUE FOUND
        ....
    }

  1. The Luhn credit card algorithm....

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

//  THE FUNCTION RECEIVES AN ARRAY OF CHARACTERS, WITHOUT SPECIFYING ITS LENGTH
bool luhn(char creditcard[])
{
    int  s1  = 0;
    int  s2  = 0;
    bool odd = true;

//  ITERATE OVER THE STRING BACKWARDS
    for(int i = strlen(creditcard)-1 ; i >= 0  ; i = i-1) {
        char digit = creditcard[i] - '0';

        if(odd) {
            s1 += digit;
        }
        else {
            int mult = digit*2;
            s2 += (mult/10) + (mult%10);
        }
        odd     = !odd;
    }
    return ((s1+s2) % 10) == 0;
}

int main(int argcount, char *argvalue[])
{
//  ITERATE OVER EACH COMMAND-LINE ARGUMENT
    for(int a=1 ; a<argcount ; ++a) {
        if(luhn(argvalue[a])) {
            printf("%16s\t%s\n", argvalue[a], "OK");
        }
        else {
            printf("%16s\t%s\n", argvalue[a], "not OK");
        }
    }
    return 0;
}

  1. Write a program that prints out the ordinal description of the (assumed to be numerical) arguments supplied to the program. For example:

    prompt> ./ordinal 1 6 11 12 21 22 23 1st 6th 11th 12th 21st 22nd 23rd

void ordinal(int i)
{
    int lastdigit = i % 10;    // keep the remainder after dividing by 10

    if(lastdigit == 1 && i != 11) {
        printf("%ist\n", i);
    } else if(lastdigit == 2 && i != 12) {
        printf("%ind\n", i);
    } else if(lastdigit == 3 && i != 13) {
        printf("%ird\n", i);
    } else {
        printf("%ith\n", i);
    }
}

int main(int argcount, char *argvalue[])
{
    for(int a=1 ; a<argcount ; a = a+1) {
        ordinal( atoi(argvalue[a]) );
    }
    return 0;
}

  1. Write programs to print each of these shapes (refer to the Labsheet). Use C's for loops to control your printing, rather than just 'fixed' calls to printf (imagine if a command-line argument indicated how big the Christmas tree should be!):

// Q6a)
for(int row = 1 ; row <= 5 ; ++row) {
    for(int col = 1 ; col <= row ; col = col+1) {
        printf("*");
    }
    printf("\n");
}

// Q6b)
for(int row = 1 ; row <= 5 ; ++row) {
    for(int col = 1 ; col <= (5-row) ; col = col+1) {
        printf(" ");
    }
    for(int col = 1 ; col <= row ; col = col+1) {
        printf("*");
    }
    printf("\n");
}

// Q6c)
for(int row = 5 ; row >= 1 ; --row) {
    for(int col = 1 ; col <= row ; col = col+1) {
        printf("*");
    }
    printf("\n");
}

// Q6d)
for(int row = 1 ; row <= 5 ; ++row) {
    for(int col = 1 ; col <= 5-row ; col = col+1) {
        printf(" ");
    }
    for(int col = 1 ; col <= row*2 - 1 ; col = col+1) {
        printf("*");
    }
    printf("\n");
}

Department of Computer Science and Software Engineering

This Page

Written by: [email protected]