Programming Fundamentals
Information
- This page contains extra challenge exercises for week 07.
- These exercises are not compulsory, nor do they provide any marks in the course.
- These exercises are intended for students that want more challenge in the course.
- You cannot submit any of these exercises, however autotests are available for them (Command included at bottom of each exercise).
Exercise
(●●◌)
:
Count File Lines
Write a program called count_file_lines.c
that takes in
a file name from the terminal and prints out the number of lines in
that file
Creating a file
At this point in the course, you have created C files for all your exercises. Text editors such as gedit are capable of handling any type of file containing text. We are going to open new file with gedit that we will access in our C program. Run the following command:
gedit text_file.txt &
Now, put whatever text you want inside of this file. For our example, we will use:
We're no strangers to love You know the rules and so do I A full commitment's what I'm thinking of You wouldn't get this from any other guy
Opening a File
The first important thing to do is make sure you have
#include <stdio.h>
in your program. From here, you can include the
line:
FILE *file = fopen("text_file.txt", "r");
On the left-hand side, we are creating a variable file
that is
a pointer to a FILE
. You do not need to understand what
FILE
is, just know that it is the type of data that
file
wants to point at.
On the right-hand side, we are calling a function fopen()
. This
function takes in the name of the file that we want to read as well as the
"mode" to access the file.
There are many modes
to access the file in, however, we are using "r" as this corresponds to "read"
since we want to read the file in our case.
As an overview, this line of code is creating a pointer to the file we just created, which we can now access in our C program!
Reading from a File
Now, reading a line from the file is almost identical to how we have read lines in lab07.
First, we create an array of characters to read the line into:
char line[MAX_SIZE];
Then we can use fgets()
in a very similar manner:
fgets(line, MAX_SIZE, file);
The difference in fgets()
here is that we have replaced
stdin
with file
. In simple terms, fgets()
will take input from whatever place the third parameter points to. In the case
of stdin
, it will take input from the terminal and in the case of
file
, it will take input from the file we specified.
We can now print out the contents of line
like so:
printf("%s", line);
And we should receive this in the terminal:
We're no strangers to love
If we were to call fgets()
in exactly the same way as before,
it will then scan the next line of the file which we could print out.
Run the commands below and compile the C file optained to see how the text file can be printed.
Download file_example.c here, or copy it to your CSE account using the following command:
cp -n /web/cs1511/23T1/activities/count_file_lines/example_file_io/file_example.c .
Download text_file.txt here, or copy it to your CSE account using the following command:
cp -n /web/cs1511/23T1/activities/count_file_lines/example_file_io/text_file.txt .
Back to the program
Now that we understand files, we can continue. In this exercise, you are
to write code in count_file_lines.c
that takes a file name as
input and prints out how many lines are in that file.
You will need to make your own files to test this as none will be provided. Some examples are provided below, you can assume that the files provided will have the correct number of lines seen in the output.
./count_file_lines super_secret_file.txt 'super_secret_file.txt' contains 7893 lines. ./count_file_lines meaning_of_life.txt 'meaning_of_life.txt' contains 42 lines. ./count_file_lines count_file_lines.c 'count_file_lines.c' contains 34 lines.
When you think your program is working,
you can use autotest
to run some simple automated tests:
1511 autotest count_file_lines
Exercise
(☠)
:
Extra-hard challenge: Cracking A Substitution Cipher
Your program should make no assumptions about the language of the original text - don't assume its English. In other words don't hard code English properties into your program, extract the statistical properties from the sample plain text. However, you can assume the English alphabet ('a'..'z').
Your program will be given as its first line of input the name of a file containing a large amount of unencrypted text in the same language as the encrypted text.
For example for example your program might be given this file containing 188k characters of English text (wikipedia sentences from here) Your program will be given the encrypted text on the next lines. You may read it all before printing the decryption.
For example:
./crack_substitution wiki_sentences.txt M'ka paat dra qegbu, ueta md xbb Rxu vw fxya teq Umxvetup, ogmbbmxtd, mt Oab-Xmg teq Red psvvag tmlrdp, vmu Jsbw Qrat wes xtu M qaga negakag qmbu Dra fgxzw uxwp, fmdw bmlrdp Dra qxw wes'u cbxw qmdr va bmya x frmbu Qmbb wes pdmbb beka va Qrat M'v te betlag westl xtu oaxsdmnsb? Qmbb wes pdmbb beka va Qrat M'ka led tedrmtl osd vw xfrmtl pesb? M yteq wes qmbb, M yteq wes qmbb M yteq drxd wes qmbb Qmbb wes pdmbb beka va qrat M'v te betlag oaxsdmnsb? M'ka paat dra qegbu, bmd md sc Xp vw pdxla teq Frxbbatlmtl xtlabp mt x taq xla teq Red psvvag uxwp, gefy t gebb Dra qxw wes cbxw neg va xd wesg preq Xtu xbb dra qxwp, M led de yteq Wesg cgaddw nxfa xtu abafdgmf pesb I've seen the world, done it all Had my cake now Diamonds, brilliant, in Bel-Air now Hot summer nights, mid July When you and I were forever wild The crazy days, city lights The way you'd play with me like a child Will you still love me When I'm no longer young and beautiful? Will you still love me When I've got nothing but my aching soul? I know you will, I know you will I know that you will Will you still love me when I'm no longer beautiful? I've seen the world, lit it up As my stage now Challenging angels in a new age now Hot summer days, rock n roll The way you play for me at your show And all the ways, I got to know Your pretty face and electric soulYou may assume the filename given on the first line of input is at most 1000 characters.
You may assume the encrypted text on stdin contains at most 10000 characters.
You may assume the unencrypted example text in the file contains at most 250000 characters.
Hint: you will need to look at the probabilities of sequences of 2 or perhaps 3 letters occurring or perhaps the probabilities of words.
Hint: use fopen
to open the file and fgetc
to read the file.
These won't be covered in lectures, so read this
example program to see how to use this functions to read a file.
An autotest is available to help you test your program but because this is a difficult problem it is possible very good attempts at the problem won't pass the autotests.
When you think your program is working,
you can use autotest
to run some simple automated tests:
1511 autotest crack_substitution