Programming Fundamentals
Objectives
- introduction to pointers
- scanning until ctrl-d
- processing of characters and strings
- use of functions
Feedback Week!
In this week's lab, your tutors will go around the class and give you one on one feedback on some code you have written in a previous week.
Take this as an opportunity to ask any questions you might have about the course content so far!
So, if you would like, have a think about if there is any particular exercise you would like to receive feedback for, or any particular content you would like to ask about.
Reminder: Help sessions
Help sessions are running this week!
These are one of the best ways for you to get one on one help with a tutor for any course content (including Lab Exercises and Assignments).
For the dates and times of the help sessions, see the Help Session Timetable.
To join a help session, or for more information, see the COMP(1511|1911) Help Session Microsoft Teams.
For face-to-face help sessions, the lab map can be found here. If help sessions are running in other buildings you can use Lost on Campus to help you find them.
Activities To Be Completed
The following is a list of all the activities available to complete this week...
Worth 1 mark(s) in total:
- print_address
- debug_increment
- array_sum_prod
- swap_pointers
- my_scanf
- string_match
Worth 1 mark(s) in total:
- summation
- stellar_information
- substitution
Worth 0.5 mark(s) in total:
- frequency_analysis
For your interest, but not for marks:
- word_search
Problem sets are capped at 15 marks (there are 4 possible bonus marks from the three-dot exercises that can bring you up to a total of 15 if you missed out on any other marks in the one- or two-dot exercises).
Completing just the one and two-dot exercises every week can give you the full 15 marks needed in this component.
For more details, see the course outline.
Preparation
Before the lab you should re-read the relevant lecture slides and their accompanying examples.
When attempting the following exercises, make sure to read the whole exercise, including any hints and assumptions that may make the exercise easier.
Videos
The following short videos may be of some help to get started on the lab exercises.
If you have watched the videos and are still unsure how to start the exercises, ask your tutor for help :)
- Revision, pointers: youtube
Exercise
(●◌◌)
:
Print Address
Download print_address.c here
Or, copy these file(s) to your CSE account using the following command:
1511 fetch-activity print_addressIn this activity, you will complete the C program
print_address.c
which attempts to print a memory address and value at that address, using pointers.
In main
, you are provided with a variable number
of type int
and a supposed pointer to number
called number_pointer
.
Your main
should do the following;
- Correctly initialise the pointer
number_pointer
to point to the address ofnumber
. In the provided code, the pointer is declared incorrectly, you will need to fix this before you can initialise it. - Print the memory address stored in
number_pointer
. - Call the function
print_at_address
and pass the memory address stored innumber_pointer
to it.
The print_at_address
will need to be implemented by you and it should;
- Print the memory address passed to it.
- Print the value at that memory address.
You must not change the function signature of print_at_address
.
Examples
dcc print_address.c -o print_address ./print_address Passing the memory address 0x16b44b028 to the function The memory address passed to this function is 0x16b44b028 The value at the memory address is 42
Assumptions/Restrictions/Clarifications
- You must not change the function signature of
print_at_address
. - You must use the function
print_at_address
to print the second and third lines of the output.
1511 style print_address.c
When you think your program is working,
you can use autotest
to run some simple automated tests:
1511 autotest print_address
When you are finished working on this exercise,
you and your lab partner must both
submit your work by running give
:
give cs1511 lab07_print_address print_address.c
Note, even though this is a pair exercise,
you both must run give
from your own account
before Monday 28 October 20:00
to obtain the marks for this lab exercise.
print_address.c
// Print the memory address of a variable
// Created by: Ibrahim Ghoneim z5470570 03/2024
// print_at_address.c
#include <stdio.h>
void print_at_address(int *memory_address);
int main(void) {
int number = 42;
////////////////////////////////////////////////////////////////////////////
////////////////////////// ONLY MODIFY CODE BELOW //////////////////////////
////////////////////////////////////////////////////////////////////////////
int *number_pointer = &number;
printf("Passing the memory address %p to the function\n", number_pointer);
print_at_address(number_pointer);
return 0;
}
/*
param: memory_address - is an integer pointer that points to a memory address
return: void
Prints the memory address and the value at the memory address
*/
void print_at_address(int *memory_address) {
printf("The memory address passed to this function is %p\n", memory_address);
printf("The value at the memory address is %d\n", *memory_address);
return;
}
Exercise
(●◌◌)
:
Debugging - increment
Download debug_increment.c here
Or, copy these file(s) to your CSE account using the following command:
1511 fetch-activity debug_increment
Debugging Tips!
Some debugging tips for you:
- dcc output - as you run into issues, dcc will point you to where the errors are. Remember that dcc gives you the line number the issue is on, and will give some sort of explanation. Make sure you read everything dcc gives you. Sometimes we get “errors carried forward”, so find your first error, fix that, then recompile.
- print statements - sometimes it can be handy to see if the flow of your code puts you in the spot you expect it to be (ie. inside the right if statement, or going through a loop the correct amount of times). A quick way you can check this is by putting print statements in your code for testing purposes, like
"the value of x is %d and y is %d"
. This lets you check that you got against what you expected. - COMP1511 debugging guide
The Task
This exercise takes in a number and intends to increment the value of the number using a function increment()
, which takes a pointer to an integer as its parameter.
Currently it has some issues - it is your job to figure them out and fix the code.
Examples
dcc debug_increment.c -o debug_increment ./debug_increment Please enter a number: 1 Before increment: 1 After increment: 2 ./debug_increment Please enter a number: -8 Before increment: -8 After increment: -7 ./debug_increment Please enter a number: 100 Before increment: 100 After increment: 101
1511 style debug_increment.c
When you think your program is working,
you can use autotest
to run some simple automated tests:
1511 autotest debug_increment
When you are finished working on this exercise,
you must
submit your work by running give
:
give cs1511 lab07_debug_increment debug_increment.c
You must run give
before Monday 28 October 20:00
to obtain the marks for this lab exercise.
Note that this is an individual exercise,
the work you submit with give
must be entirely your own.
debug_increment.c
// debug_pointers.c
// This program given a number, incraments it using pointers
// Written by Sofia De Bellis, z5418801 on July 2023
#include <stdio.h>
void increment(int *ptr);
int main() {
int num;
printf("Please enter a number: ");
scanf("%d", &num);
int *ptr = #
printf("Before increment: %d\n", *ptr);
increment(ptr);
printf("After increment: %d\n", *ptr);
return 0;
}
void increment(int *ptr) {
(*ptr)++;
}
Exercise
(●◌◌)
:
Calculate both the sum and product of the values in an array
Download array_sum_prod.c here
Or, copy these file(s) to your CSE account using the following command:
1511 fetch-activity array_sum_prod
Your task is to add code to this function in array_sum_prod.c:
// Calculates the sum and product of the array nums.
// Actually modifies the variables that *sum and *product are pointing to
void array_sum_prod(int length, int nums[length], int *sum, int *product) {
// TODO: Complete this function
}
The above file array_sum_prod.c
contains a function
array_sum_prod
, which should find the sum and the product of the
values stored in the array. It should write these values into the integers
referenced by the pointers in the input to the function.
Unfortunately, the provided function doesn't actually work. For this lab exercise, your task is to complete this function.
The file also contains a main function which you can use to help test
your array_sum_prod
function. It has two simple test cases.
This main function will not be marked -- you must write all of your code
in the array_sum_prod
function.
You may modify the main function if you wish (e.g. to add further tests),
but only the array_sum_prod
function will be marked.
Examples
dcc -o array_sum_prod array_sum_prod.c ./array_sum_prod Sum: 20, Product: 360 Sum: 10, Product: 24
Assumptions/Restrictions/Clarifications
- You will not be given an empty array as input, you can assume that you have at least 1 value.
1511 style array_sum_prod.c
When you think your program is working,
you can use autotest
to run some simple automated tests:
1511 autotest array_sum_prod
When you are finished working on this exercise,
you and your lab partner must both
submit your work by running give
:
give cs1511 lab07_array_sum_prod array_sum_prod.c
Note, even though this is a pair exercise,
you both must run give
from your own account
before Monday 28 October 20:00
to obtain the marks for this lab exercise.
array_sum_prod.c
// COMP1511 Array Sum Product
// Calculate the sum and the product of the elements in an array
// and write the results into variables passed into the function
// by reference.
// Modified by Marc Chee, March 2020
#include <stdio.h>
void array_sum_prod(int length, int nums[length], int *sum, int *product);
// This is a simple main function that you can use to test your array_sum_prod
// function.
// It will not be marked - only your array_sum_prod function will be marked.
//
// Note: the autotest does not call this main function!
// It calls your array_sum_prod function directly.
// Any changes that you make to this main function will not affect the autotests.
int main(int argc, char *argv[]){
int nums[] = {3,4,1,5,6,1};
int prod;
int sum;
//Pass in the address of the sum and product variables
array_sum_prod(6, nums, &sum, &prod);
printf("The sum is %d and prod is %d\n",sum,prod);
return 0;
}
// Calculates the sum and product of the array nums.
// Actually modifies the variables that *sum and *product are pointing to
void array_sum_prod(int length, int nums[length], int *sum, int *product) {
int i = 0;
*sum = 0;
*product = 1;
while (i < length) {
*sum = *sum + nums[i];
*product = *product * nums[i];
i++;
}
}
Exercise
(●◌◌)
:
Using pointers and a function to swap number values
Download swap_pointers.c here
Or, copy these file(s) to your CSE account using the following command:
1511 fetch-activity swap_pointers
Your task is to add code to this function in swap_pointers.c:
// swap the values in two integers, given as pointers
void swap_pointers(int *a, int *b) {
// PUT YOUR CODE HERE
}
swap_pointers
should take two pointers to integers as input and swap the
values stored in those two integers.
For example if the integers are:
int first = 1; int second = 2;
After your function runs, first should be 2 and second should be 1.
Assumptions/Restrictions/Clarifications
swap_pointers
is a void function. It cannot return any values.swap_pointers
should not call scanf (or getchar or fgets).swap_pointers
should not print anything. It should not call printf.- Your submitted file may contain a main function. It will not be tested or marked.
1511 style swap_pointers.c
When you think your program is working,
you can use autotest
to run some simple automated tests:
1511 autotest swap_pointers
When you are finished working on this exercise,
you must
submit your work by running give
:
give cs1511 lab07_swap_pointers swap_pointers.c
You must run give
before Monday 28 October 20:00
to obtain the marks for this lab exercise.
Note that this is an individual exercise,
the work you submit with give
must be entirely your own.
swap_pointers.c
#include <stdio.h>
// swap the values in two integers, given as pointers
void swap_pointers(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
// This is a simple main function which could be used
// to test your swap_pointers function.
// It will not be marked.
// Only your swap_pointers function will be marked.
int main(void) {
int first = 1;
int second = 2;
swap_pointers(&first, &second);
printf("%d, %d\n", first, second);
return 0;
}
Exercise
(●◌◌)
:
My Scanf
Download my_scanf.c here
Or, copy these file(s) to your CSE account using the following command:
1511 fetch-activity my_scanf
Ben Briant has decided to learn how scanf()
works, and to help with his
understanding, he has decided to write his own simple scanf functions!
They are much simpler than a regular scanf, as they only allow for scanning in
a single integer or a single double (depending on if my_scanf_int()
or
my_scanf_double()
is being called) at a time.
Both of these functions should:
- take in a pointer to a variable that we want to scan our value into,
- read a value from the user (using regular scanf), then
- set the value of the input to be the value read from the user.
Unfortunately, Ben got overwhelmed with all the pointer syntax (*
and &
),
so decided to just avoid writing any of it! Your job is to put all the *
and
&
in the correct spots in the code.
You will have to edit both the main()
function, my_scanf_int()
and
my_scanf_double()
, But you can't change any part of the code aside
from adding *
or &
.
Examples
dcc my_scanf.c -o my_scanf ./my_scanf Enter the amount of study you need to do this week (in decimal): 7.5 Enter the number of days you have free: 3 You have on average 2.50 hour(s) each free day to do homework.
Testing
When testing your program, we are checking more than that it simply produces the correct output. We are also testing that the functions work correctly individually (by replacing your main function with one of our own).
1511 style my_scanf.c
When you think your program is working,
you can use autotest
to run some simple automated tests:
1511 autotest my_scanf
When you are finished working on this exercise,
you must
submit your work by running give
:
give cs1511 lab07_my_scanf my_scanf.c
You must run give
before Monday 28 October 20:00
to obtain the marks for this lab exercise.
Note that this is an individual exercise,
the work you submit with give
must be entirely your own.
my_scanf.c
// A program that creates its own simple scanf functions.
// Activity written by Paula
// This program was written by Ben Briant
// This program was fixed by [student]
#include <stdio.h>
void my_scanf_double(double *d) {
double input;
scanf("%lf", &input);
*d = input;
}
void my_scanf_int(int *i) {
int input;
scanf("%d", &input);
*i = input;
}
int main(void) {
printf("Enter the amount of study you need to do this week (in decimal): ");
double total_time;
my_scanf_double(&total_time);
printf("Enter the number of days you have free: ");
int days;
my_scanf_int(&days);
double time_per_day = total_time / days;
printf("You have on average %.2lf hour(s) each free day to do homework.\n", time_per_day);
return 0;
}
Exercise
(●◌◌)
:
String Match
Your job is to write a program called string_match.c
which lets us count the
number of times we see our "search term" in a list of strings.
TASK 1 Scan in the "search term"
TASK 2: Scan in strings from standard input until Ctrl-D is pressed.
TASK 3: Count the number of times the "search term" appear in the input.
Examples
dcc string_match.c -o string_match ./string_match Enter the search term: same Enter the list of strings: same sand same send shade same shadow There was 3 occurrence(s) of the search term in the input. ./string_match Enter the search term: An ostrich's eye is bigger than its brain. Enter the list of strings: That is a cool fact. I never knew that! An ostrich's eye is bigger than its brain. ostrich? Why the random facts? There was 1 occurrence(s) of the search term in the input. ./string_match Enter the search term: 42 is the meaning of life, the universe, and everything Enter the list of strings: The ascii for * is 42 42 is the meaning of life, the universe, and everything!!! 42 = everything There was 0 occurrence(s) of the search term in the input.
Assumptions/Restrictions/Clarifications
- You can assume that each string will be no longer than 128 characters long
- You may find the
strcmp()
function useful
1511 style string_match.c
When you think your program is working,
you can use autotest
to run some simple automated tests:
1511 autotest string_match
When you are finished working on this exercise,
you must
submit your work by running give
:
give cs1511 lab07_string_match string_match.c
You must run give
before Monday 28 October 20:00
to obtain the marks for this lab exercise.
Note that this is an individual exercise,
the work you submit with give
must be entirely your own.
string_match.c
// string_match.c
// Searches for words in standard input until ctrl + d is pressed
// that match any of the given search term
// Written by Sofia De Bellis, z5418801, on July 2023
#include <stdio.h>
#include <string.h>
#define MAX_WORD_LEN 128
int main(void) {
int num_search_terms = 0;
printf("Enter the search term: ");
char search_term[MAX_WORD_LEN];
fgets(search_term, MAX_WORD_LEN, stdin);
printf("Enter the list of strings:\n");
int total = 0;
char buf[MAX_WORD_LEN];
while (fgets(buf, MAX_WORD_LEN, stdin) != NULL) {
if (strcmp(buf, search_term) == 0) {
total++;
}
}
printf("There was %d occurrence(s) of the search term in the input.\n",
total);
return 0;
}
Exercise
(●●◌)
:
Summation
Write a C program summation.c
that takes integers as command line arguments
and calculates their sum.
Examples
dcc summation.c -o summation ./summation 1 2 3 4 5 6 7 8 9 Sum: 45 ./summation -5 10 -15 20 Sum: 10 ./summation 100 Sum: 100 ./summation Sum: 0
Assumptions/Restrictions/Clarifications
- You may find the
atoi()
function in the C standard library (stdlib.h
) useful. - You may assume that
argv[0]
will always be the program name and all subsequent elements will be integers.
1511 style summation.c
When you think your program is working,
you can use autotest
to run some simple automated tests:
1511 autotest summation
When you are finished working on this exercise,
you must
submit your work by running give
:
give cs1511 lab07_summation summation.c
You must run give
before Monday 28 October 20:00
to obtain the marks for this lab exercise.
Note that this is an individual exercise,
the work you submit with give
must be entirely your own.
summation.c
// summation.c
//
// This program calculates and outputs the sum of all the integers provided as
// command line arguments.
//
// Written by Sofia De Bellis, z5418801, July 2023
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[]) {
int sum = 0;
// Start from index 1 to skip the program name (argv[0])
for (int i = 1; i < argc; i++) {
// Convert each command line argument to an integer using atoi() and
// add the current number to the sum
sum += atoi(argv[i]);
}
printf("Sum: %d\n", sum);
return 0;
}
Exercise
(●●◌)
:
Stellar Information Capture
Download stellar_information.c here
Or, copy these file(s) to your CSE account using the following command:
1511 fetch-activity stellar_information
Write a C program stellar_information.c
that simulates a star system in space.
Each star in the system is represented by a structure containing its name, distance from Earth (in light-years),
and spectral type. Your task is to initialize a pointer to a star structure, write a function to populate its fields,
a function to calculate an estimate for the time it would take to travel from earth to the star
and a function to print the star's information and the estimate for the time it would take to travel from earth to the star.
Task 1
Define a structure named star
with the following fields:
name
: a string of size 50 to store the star's name.distance
: a double to store the star's distance from Earth in light-years.spectral_type
: a character to store the star's spectral type (e.g., O, B, A, F, G, K, M).
Task 2
Declare a pointer star_ptr
to a star
structure.
Task 3
Write the function called input_star_information()
that prompts the user to enter the star's name,
distance from Earth, and spectral type. Then store the input values in the respective fields
of the structure pointed to by star_ptr
.
Task 4
Write the function called time_travel()
that, given a pointer to a star, calculates and returns the
estimated travel time from Earth to the star based on star's distance. This calculation involves the following steps:
- Converting the stars distance from light-years to kilometers by multiplying the distance by the
CONVERSION_CONSTANT
that is defined at the top of your program. - Dividing that previously calculated value by the
LIGHT_SPEED
constant which is defined at the top of your program.
Task 5
Write the function called print_star_information()
that, given a pointer to a star, prints the star's information
(name, distance, spectral type, and time travel).
Examples
dcc stellar_information.c -o stellar_information ./stellar_information Enter the star's name: Sirius Enter the star's distance from Earth (in light-years): 8.6 Enter the star's spectral type: A Star's Information: Name: Sirius Distance: 8.600000 light-years Spectral Type: A Estimated travel time from Earth: 271403091.80 seconds ./stellar_information Enter the star's name: Polaris Enter the star's distance from Earth (in light-years): 323 Enter the star's spectral type: F Star's Information: Name: Polaris Distance: 323.000000 light-years Spectral Type: F Estimated travel time from Earth: 10193395192.08 seconds ./stellar_information Enter the star's name: Rigel Enter the star's distance from Earth (in light-years): 864.3 Enter the star's spectral type: B Star's Information: Name: Rigel Distance: 864.300000 light-years Spectral Type: B Estimated travel time from Earth: 27276010726.06 seconds
Assumptions/Restrictions/Clarifications
- You may assume that valid input will always be given
- You may find using %.2lf useful for printing the travel time value to two decimal places
1511 style stellar_information.c
When you think your program is working,
you can use autotest
to run some simple automated tests:
1511 autotest stellar_information
When you are finished working on this exercise,
you must
submit your work by running give
:
give cs1511 lab07_stellar_information stellar_information.c
You must run give
before Monday 28 October 20:00
to obtain the marks for this lab exercise.
Note that this is an individual exercise,
the work you submit with give
must be entirely your own.
stellar_information.c
// stellar_information.c
// This program simulates a star system in space
// Written by Sofia De Bellis, z5418801, July 2023
#include <stdio.h>
#include <stdlib.h>
#define CONVERSION_CONSTANT 9.461e12
#define LIGHT_SPEED 299792.458
struct star {
char name[50];
double distance;
char spectral_type;
};
void print_star_information(struct star* star);
void input_star_information(struct star* star);
double time_travel(struct star* star);
int main(void) {
struct star star;
struct star *star_ptr = ☆
input_star_information(star_ptr);
print_star_information(star_ptr);
return 0;
}
// Takes in the stars information
void input_star_information(struct star* star) {
printf("Enter the star's name: ");
fgets(star->name, 50, stdin);
printf("Enter the star's distance from Earth (in light-years): ");
scanf("%lf", &star->distance);
printf("Enter the star's spectral type: ");
scanf(" %c", &star->spectral_type);
}
// Prints the stars information
void print_star_information(struct star* star) {
printf("\nStar's Information:\n");
printf("Name: %s", star->name);
printf("Distance: %lf light-years\n", star->distance);
printf("Spectral Type: %c\n", star->spectral_type);
printf("Estimated travel time from Earth: %.2lf seconds\n", time_travel(star));
}
// Estimate travel time from Earth to the star based on star's distance
double time_travel(struct star* star) {
double distance_km = star->distance * CONVERSION_CONSTANT;
double travel_time = distance_km / LIGHT_SPEED;
return travel_time;
}
Exercise
(●●◌)
:
Encrypting Text with a Substitution Cipher
Write a C program substitution.c
which reads characters from its input and
writes the characters to its output encrypted with a
Substitution cipher.
A Substitution cipher maps each letter to another letter.
The mapping will be given to your program via the command line as a command line argument
(no spaces between any characters). This is all on one line. This input will contain 26
characters: an ordering of the letters 'a'..'z'
.
Characters other than letters should not be encrypted.
Your program should stop only at the end of input.
Your program should contain at least one function other than main.
Examples
dcc substitution.c -o substitution ./substitution qwertyuiopasdfghjklzxcvbnm Enter text: I was scared of dentists and the dark O vql leqktr gy rtfzolzl qfr zit rqka I was scared of pretty girls and starting conversations O vql leqktr gy hktzzn uoksl qfr lzqkzofu egfctklqzogfl ./substitution abcdefghijklmnopqrstuvwxyz Enter text: The identity cipher!!! The identity cipher!!! ./substitution bcdefghijklmnopqrstuvwxyza Enter text: The Caesar cipher is a subset of the substitution cipher! Uif Dbftbs djqifs jt b tvctfu pg uif tvctujuvujpo djqifs!
Your program will only be tested with an appropriate and valid mapping input for marking - but a good programmer would check the input is present and appropriate.
1511 style substitution.c
When you think your program is working,
you can use autotest
to run some simple automated tests:
1511 autotest substitution
When you are finished working on this exercise,
you and your lab partner must both
submit your work by running give
:
give cs1511 lab07_substitution substitution.c
Note, even though this is a pair exercise,
you both must run give
from your own account
before Monday 28 October 20:00
to obtain the marks for this lab exercise.
substitution.c
// Substitution.c
// Write stdin to stdout encrypted with a Substitution cipher
// https://en.wikipedia.org/wiki/Substitution_cipher
//
// The mapping will be supplied as a command-line argument containing 26 characters:
// These will be an an ordering of the letters 'a'..'z'.
//
// Written 3/3/2018 by Andrew Taylor (andrewt@unsw.edu.au)
// and adapted for 23T2 by Sofia De Bellis, z5418801 on July 2023
#include <stdio.h>
#include <string.h>
#define ALPHABET_SIZE 26
int encrypt(char character, char mapping[ALPHABET_SIZE]);
int main(int argc, char *argv[]) {
char mapping[ALPHABET_SIZE + 1];
for (int i = 0; i < ALPHABET_SIZE; i++) {
mapping[i] = argv[1][i];
}
mapping[ALPHABET_SIZE] = '\0';
// Error checking - not necessary in student solution or tested
if (mapping[0] == '\0') {
printf("Usage: ./substitution <mapping>\n");
return 1;
}
if (strlen(mapping) != ALPHABET_SIZE) {
printf("./substitution: mapping must contain %d letters\n", ALPHABET_SIZE);
return 1;
}
printf("Enter text:\n");
char character;
while (scanf("%c", &character) == 1) {
int encrypted_character = encrypt(character, mapping);
printf("%c", encrypted_character);
}
return 0;
}
// encrypt letters with a substitution cipher with the specified mapping
int encrypt(char character, char mapping[ALPHABET_SIZE]) {
if (character >= 'A' && character <= 'Z') {
return mapping[character - 'A'] - 'a' + 'A';
} else if (character >= 'a' && character <= 'z') {
return mapping[character - 'a'];
} else {
return character;
}
}
Exercise
(●●●)
:
Frequency Analysis
Write a C program frequency_analysis.c
which reads characters from its input
until end of input.
It should then print the occurrence frequency for each of the 26 letters
'a'..'z'
.
The frequency should be printed as a decimal value and an absolute number in exactly the format below.
Note upper and lower case letters are counted together.
Examples
dcc frequency_analysis.c -o frequency_analysis ./frequency_analysis Hello and goodbye. 'a' 0.066667 1 'b' 0.066667 1 'c' 0.000000 0 'd' 0.133333 2 'e' 0.133333 2 'f' 0.000000 0 'g' 0.066667 1 'h' 0.066667 1 'i' 0.000000 0 'j' 0.000000 0 'k' 0.000000 0 'l' 0.133333 2 'm' 0.000000 0 'n' 0.066667 1 'o' 0.200000 3 'p' 0.000000 0 'q' 0.000000 0 'r' 0.000000 0 's' 0.000000 0 't' 0.000000 0 'u' 0.000000 0 'v' 0.000000 0 'w' 0.000000 0 'x' 0.000000 0 'y' 0.066667 1 'z' 0.000000 0 ./frequency_analysis Hey! Hey! Hey! I don't like walking around this old and empty house So hold my hand, I'll walk with you my dear 'a' 0.072289 6 'b' 0.000000 0 'c' 0.000000 0 'd' 0.084337 7 'e' 0.084337 7 'f' 0.000000 0 'g' 0.012048 1 'h' 0.096386 8 'i' 0.072289 6 'j' 0.000000 0 'k' 0.036145 3 'l' 0.084337 7 'm' 0.036145 3 'n' 0.060241 5 'o' 0.084337 7 'p' 0.012048 1 'q' 0.000000 0 'r' 0.024096 2 's' 0.036145 3 't' 0.048193 4 'u' 0.036145 3 'v' 0.000000 0 'w' 0.036145 3 'x' 0.000000 0 'y' 0.084337 7 'z' 0.000000 0
Hint: use an array to store counts of each letter.
Hint: make sure you understand this example program which counts integers from the range 0..99.
Manually Cracking a Substitution Cipher
This English text was encrypted with a substitution cipher.
Di jd, vdl'ht xtqa dh O qn Vdl rdlwk O'ss wdkith htqromu omkd ok O fhdwqwsv xdm'k Styk kd nv dxm rtzoetj Wlk kiqk'j kit royythtmet om dlh dfomodmj Vdl'ht q ndlkiyls Kiqk qndlmkj ydh qmdkith xtta dm nv dxm Mdx O'n q mdzts nqrt htjdlhetyls O jkqhk q eiqom xoki nv kidluik Kqsa oj eitqf, nv rqhsomu Xitm vdl'ht yttsomu houik qk idnt O xqmmq nqat vdl ndzt xoki edmyortmet O xqmmq wt xoki vdl qsdmt
What was the original text?
Mapping: qwertyuiopasnmdfghjklzxcvb
Oh so, you're weak or I am You doubt I'll bother reading into it I probably won't Left to my own devices But that's the difference in our opinions You're a mouthful That amounts for another week on my own Now I'm a novel made resourceful I start a chain with my thought Talk is cheap, my darling When you're feeling right at home I wanna make you move with confidence I wanna be with you alone
1511 style frequency_analysis.c
When you think your program is working,
you can use autotest
to run some simple automated tests:
1511 autotest frequency_analysis
When you are finished working on this exercise,
you must
submit your work by running give
:
give cs1511 lab07_frequency_analysis frequency_analysis.c
You must run give
before Monday 28 October 20:00
to obtain the marks for this lab exercise.
Note that this is an individual exercise,
the work you submit with give
must be entirely your own.
frequency_analysis.c
// Written 3/3/2018 by Andrew Taylor (andrewt@unsw.edu.au)
// Read characters from stdin until of input then print the frequency of letters
#include <stdio.h>
#define NOT_A_LETTER (-1)
#define ALPHABET_SIZE 26
int get_letter_frequencies(int letter_count[ALPHABET_SIZE]);
int letter_index(int character);
void print_frequencies(int letter_count[ALPHABET_SIZE], int n_letters_read);
int main(int argc, char *argv[]) {
int letter_count[ALPHABET_SIZE] = {0}; // 1 array element for each English letter
int n_letters_read = get_letter_frequencies(letter_count);
print_frequencies(letter_count, n_letters_read);
return 0;
}
// read characters from stdin, and for uppercase and lower case letters updating
// accumulating count a letter_count in letter_frequencies
// number of uppercase and lower case letters read is returned
int get_letter_frequencies(int letter_count[ALPHABET_SIZE]) {
char character;
int n_letters_read = 0;
while (scanf(" %c", &character) == 1) {
int index = letter_index(character);
if (index != NOT_A_LETTER) {
letter_count[index] = letter_count[index] + 1;
n_letters_read = n_letters_read + 1;
}
}
return n_letters_read;
}
// return position of letter in English alphabet (0..25)
// for lower case and upper case letter
// return NOT_A_LETTER for other characters
int letter_index(int character) {
if (character >= 'A' && character <= 'Z') {
return character - 'A';
} else if (character >= 'a' && character <= 'z') {
return character - 'a';
} else {
return NOT_A_LETTER;
}
}
void print_frequencies(int letter_count[ALPHABET_SIZE], int n_letters_read) {
if (n_letters_read == 0) {
return;
}
int i = 0;
while (i < ALPHABET_SIZE) {
printf("'%c' %lf %d\n", 'a'+i, letter_count[i]/(double)n_letters_read, letter_count[i]);
i = i + 1;
}
}
Exercise
(☠)
:
Solving a 3D word search
Write a C program word_search.c
which takes in as input from terminal:
- A number
n
followed by any number of words - An
n x n x n
cube of characters
Note
This exercise requires the use of 3D arrays.
3D arrays are outside the scope of this course. The use of them in this exercise is simply to allow those that are interested to use/explore them.
Reminder: This exercise is not worth any marks, so do not feel obliged to learn things that aren't in this course!
Before reading any further, it is important to note that you will be expected to use 3D arrays in this exercise (although it is possible without them). A small snippet on how to create a 3d array is shown below.
#include <stdio.h>
#define X_SIZE 5
#define Y_SIZE 3
#define Z_SIZE 7
int main(void) {
// Declaring a 3D array of integers and initialising all elements to 0
int cube[X_SIZE][Y_SIZE][Z_SIZE] = {0};
// Filling element at index (2, 1, 5) with value '6'
cube[2][1][5] = 6;
// Printing this value
printf("%d", cube[2][1][6]);
}
A 3D array can be thought of in a couple of ways:
- A Rectangular prism made up of small cubes (each array element)
- An array of 2D arrays
- An array of arrays of arrays
In this exercise, there is a cube which represents a 3D word-search grid. This cube is filled in by from values scanned in when the program is actually run. Your goal is to determine whether each of the provided words in the given input arguments can be found within this cube.
The rules for finding a word are as follows:
- Words can only appear in straight lines in the cube
- Words will only be going through one dimension of the cube, this means if a
word is found through the
x
dimension, all characters in that word will have the samey
andz
positions - Words cannot exist as diagonals
- Words will not appear backwards. This means that words can only be found when going through each dimension. In terms of how this would work with a 3D array, you will never need to go backwards from an index when searching for a word
Examples
dcc word_search.c -o word_search ./word_search Please enter cube length: 2 Please enter grid 0: oa np Please enter grid 1: on ai on on found! an an found! po po not found! pi pi found! ai ai found! pa pa not found! ./word_search Please enter cube length: 3 Please enter grid 0: daa ood gwd Please enter grid 1: opb pda pod Please enter grid 2: opo edm sup dog dog found! doge doge not found! cat cat not found! ood ood found! add add found! friend friend not found! app app found! op op found! man man not found! bad bad found! long long not found! dam dam found! supercalifragilisticexpialidocious supercalifragilisticexpialidocious not found! low low not found! woo woo not found! moo moo not found! pod pod found! lip lip not found!
Assumptions/Restrictions/Clarifications
- You will always be given an integer as the first input
- All inputs will be valid
- The cube size that is input will be in the range [1, 32] inclusive
1511 style word_search.c
When you think your program is working,
you can use autotest
to run some simple automated tests:
1511 autotest word_search
word_search.c
// Program to take in a list of words then scan in a 3D cube of letters then
// print out the words that are found in this cube
// Written by Rory Golledge (z5308772) on October 2021
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define WORD_LEN 50
#define MAX_SIZE 32
#define TRUE 1
#define FALSE 0
void fill_cube(int size, int search_cube[size][size][size]);
int word_in_cube(char *word, int size, int search_cube[size][size][size]);
int find_word_from_index(
char *word,
int x, int y, int z,
int size, int search_cube[size][size][size]
);
int word_at_index(
char *word,
int *x, int *y, int *z, int *target_dimension,
int size, int search_cube[size][size][size]
);
int main(void) {
int search_cube[MAX_SIZE][MAX_SIZE][MAX_SIZE] = {0};
int size;
printf("Please enter cube length: ");
scanf(" %d", &size);
fill_cube(size, search_cube);
getchar();
putchar('\n');
char word[WORD_LEN];
while (fgets(word, WORD_LEN, stdin) != NULL) {
if (word[strlen(word) - 1] == '\n') {
word[strlen(word) - 1] = '\0';
}
if (word_in_cube(word, size, search_cube)) {
printf("%s found!\n", word);
} else {
printf("%s not found!\n", word);
}
}
return 0;
}
/*
* Fills the search cube with given input from the user
*/
void fill_cube(int size, int search_cube[size][size][size]) {
int x = 0;
while (x < size) {
printf("Please enter grid %d:\n", x);
int y = 0;
while (y < size) {
int z = 0;
while (z < size) {
search_cube[x][y][z] = getchar();
// Ignore new lines
if (search_cube[x][y][z] != '\n') {
z++;
}
}
y++;
}
x++;
}
}
/*
* Determines if a given word is found in the search cube from the provided
* rules.
*
* Returns TRUE if found, otherwise FALSE.
*/
int word_in_cube(char *word, int size, int search_cube[size][size][size]) {
int x = 0;
// This first loop can be thought of as holding each yz plane
while (x < size) {
int y = 0;
// This second loop can be though of as holding each z strip
while (y < size) {
int z = 0;
// And finally, this third loop is where all the magic happens as
// each character can be indexed here.
while (z < size) {
if (find_word_from_index(word, x, y, z, size, search_cube)) {
return TRUE;
}
z++;
}
y++;
}
x++;
}
return FALSE;
}
/*
* Finds the given word by using the index (x, y, z) as a starting point.
* Returns TRUE if found, otherwise FALSE
*/
int find_word_from_index(
char *word,
int x, int y, int z,
int size, int search_cube[size][size][size]
) {
return word_at_index(word, &x, &y, &z, &x, size, search_cube) ||
word_at_index(word, &x, &y, &z, &y, size, search_cube) ||
word_at_index(word, &x, &y, &z, &z, size, search_cube);
}
/*
* Determines if the given word is found from the current index (x, y, z) when
* looking at the target_dimension.
*
* The 'target_dimension' is a pointer with equal value to either x, y or z.
* This is simply incremented in a loop and by doing it this way, there is no
* need to check for 3 things to determine what to increment.
*
* Returns TRUE if found, otherwise FALSE
*/
int word_at_index(
char *word,
int *x, int *y, int *z, int *target_dimension,
int size, int search_cube[size][size][size]
) {
int word_length = strlen(word);
// Cannot physically find the word when it there is not enough space
if (*target_dimension + word_length > size) {
return FALSE;
}
// Just store what the original target was to maintain state
int target = *target_dimension;
int i = 0;
while (word[i] != '\0' && search_cube[*x][*y][*z] == word[i]) {
(*target_dimension)++;
i++;
}
*target_dimension = target;
if (i == word_length) {
return TRUE;
}
return FALSE;
}
Exercise — individual:
(Not For Marks) Debugging - concatenate
Download debug_concatenate.c here
Or, copy these file(s) to your CSE account using the following command:
1511 fetch-activity debug_concatenate
Note that this exercise is not marked or worth marks!
Debugging Tips!
Some debugging tips for you:
- dcc output - as you run into issues, dcc will point you to where the errors are. Remember that dcc gives you the line number the issue is on, and will give some sort of explanation. Make sure you read everything dcc gives you. Sometimes we get “errors carried forward”, so find your first error, fix that, then recompile.
- print statements - sometimes it can be handy to see if the flow of your code puts you in the spot you expect it to be (ie. inside the right if statement, or going through a loop the correct amount of times). A quick way you can check this is by putting print statements in your code for testing purposes, like
"the value of x is %d and y is %d"
. This lets you check that you got against what you expected. - COMP1511 debugging guide
The Task
This exercise concatenate the strings passed as command-line arguments excluding the filename. Currently it has some issues - it is your job to figure them out and fix the code. Additionally, think of ways you could refactor the starter code to produce a simpler solution.
Examples
dcc debug_concatenate.c -o debug_concatenate ./debug_concatenate A blue whales heartbeat can be heard over 2 miles away Concatenated string: Abluewhalesheartbeatcanbeheardover2milesaway ./debug_concatenate The moon has moonquakes Concatenated string: Themoonhasmoonquakes ./debug_concatenate Pigs cannot look up into the sky Concatenated string: Pigscannotlookupintothesky ./debug_concatenate Concatenated string:
Clarifications
- The maximum length of the resulting string is 1028 characters, including the null terminator.
Walkthrough
Below is a video walkthrough of this exercise! Make sure to attempt it before watching this video
1511 style debug_concatenate.c
When you think your program is working,
you can use autotest
to run some simple automated tests:
1511 autotest debug_concatenate
debug_concatenate.c
// debug_concatenate.c
//
// This program given command line args produces a concatenated
// string of all command line args
//
// Written by Sofia De Bellis, z5418801 on July 2023
#include <stdio.h>
#include <string.h>
#define MAX_LEN 1028
int main(int argc, char *argv[]) {
int i;
int total_length = 0;
for (i = 1; i < argc; i++) {
total_length += strnlen(argv[i], MAX_LEN);
}
char result[MAX_LEN] = "";
result[total_length + 1] = '\0';
for (i = 1; i < argc; i++) {
strncat(result, argv[i], MAX_LEN - 1);
}
printf("Concatenated string: %s\n", result);
return 0;
}
Submission
give
.
You can run give
multiple times.
Only your last submission will be marked.
Don't submit any exercises you haven't attempted.
If you are working at home, you may find it more convenient to upload your work via give's web interface.
Remember you have until Week 8 Monday 20:00 to submit your work.
You cannot obtain marks by e-mailing your code to tutors or lecturers.
You check the files you have submitted here.
Automarking will be run by the lecturer several days after the submission deadline,
using test cases different to those autotest
runs for you.
(Hint: do your own testing as well as running autotest
.)
After automarking is run by the lecturer you can view your results here. The resulting mark will also be available via give's web interface.