MTRX1702 tutorial code
Week 13
Decrypt
/*
* Example which decrypts files from encrypt, without
* requiring the password.
*
* NB: Will not work without supporting functions
* from assignment 2
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <ctype.h>
#include "encrypt.h"
int main(int argc, char* argv[])
{
char word[512];
char buf[512];
int i;
int mod;
int seed;
int valid;
FILE *fin;
FILE *fout;
FILE *word_file;
if(argc != 3)
{
printf("Usage: decrypt <input> <output>\n");
exit(1);
}
/* Open files, check if successful */
fin = fopen(argv[1], "r");
fout = fopen(argv[2], "w+"); /* fout is read and write */
word_file = fopen("words.txt", "r");
assert(word_file);
assert(fin);
assert(fout);
/* Loop over each word in dictionary */
while(fgets(word, sizeof(word), word_file))
{
/* Delete trailing newline */
word[strlen(word) - 1] = '\0';
/* Loop over each modulo value */
for(mod = 0; mod < 2; mod++)
{
/* Confirm files are ok */
assert(fin);
assert(fout);
/* Rewind to start of files */
fseek(fin, 0, SEEK_SET);
fseek(fout, 0, SEEK_SET);
/* Compute seed based on keyword
* NB: This means a file encrypted with a non
* default seed cannot be decrypted */
for(seed = 0, i = 0; word[i] != '\0'; ++i)
seed = word[i] + 31 * seed;
/* Try decryption with given password/modulo combination */
srand(seed);
encrypt(fin, fout, word, mod);
/* Flush fout, seek to start */
fflush(fout);
fseek(fout, 0, SEEK_SET);
/* Loop through fout, assume correct file contains
* only printable characters */
valid = 1;
while(1)
{
int c;
c = fgetc(fout);
if(c == EOF)
break;
if(!isspace(c) && !isalpha(c) && !isdigit(c) && !ispunct(c))
{
valid = 0;
break;
}
}
/* We've found the password */
if(valid)
{
printf("Result = %s\nModulo = %d\nMessage = ", word, mod);
fseek(fout, 0, SEEK_SET);
while(fgets(buf, sizeof(buf), fout))
printf(buf);
return 0;
}
}
}
printf("Could not decrypt file\n");
return 0;
}
Week 12
Writing test code
/* Test get_next_word() function */
#include <stdio.h>
#include "parser.h"
int main(void)
{
char *str = " hello world";
char word[100];
char *res;
res = get_next_word(word, str);
printf("Input: '%s'\n", str);
printf("Result: '%s'\n", res);
printf("Word: '%s'\n", word);
return 0;
}
|
/* Tes get_next_number() function */
#include <stdio.h>
#include "parser.h"
int main(void)
{
char *str = " 222 hello world";
int num;
char *res;
res = get_next_number(&num, str);
printf("Input: '%s'\n", str);
printf("Result: '%s'\n", res);
printf("Number: '%d'\n", num);
return 0;
}
|
/* Test parsing multiple fields */
#include <stdio.h>
#include "parser.h"
#define BUFSIZE 255
int main(void)
{
int n;
char buffer[BUFSIZE];
char word[BUFSIZE];
char *pc;
/* Example input: i test.txt 123 */
printf("Enter some input: ");
fgets(buffer, BUFSIZE, stdin);
pc = get_next_letter(buffer);
if (*pc == '\0') return 0;
printf("First letter: %c\n", *pc);
pc = get_next_word(word, pc + 1);
if (*word == '\0') return 0;
printf("Following word: %s\n", word);
pc = get_next_number(&n, pc);
if (*pc == '\0') return 0;
printf("Following number: %d\n", n);
return 0;
}
|
Pointers vs Indices
/* Using pointers */
char *get_next_letter(char *s)
{
while(!isalpha(*s) && *s != '\0')
s++;
return s;
}
|
int main(void)
{
char s[] = " abcde";
char *r;
r = get_next_letter(s);
printf("First letter is '%c'\n", *r);
printf("String starting here is '%s'\n", r);
return 0;
}
|
/* Using indices */
char *get_next_letter(char *s)
{
int i = 0;
while(!isalpha(s[i]) && s[i] != '\0')
i++;
return &s[i];
}
|
Week 11
Modular Code
/* main.c */ #include "fileio.h" #include "encrypt.h" int main(int argc, char* argv[]) { open_file(...); encrypt_data(...); return 0; }
/* fileio.h */ #include <stdio.h> FILE *open_file(char *filename); int check_file(char *filename);
/* fileio.c */ #include "fileio.h" FILE *open_file(char *filename) { FILE* file = ...; return file; } int check_file(char *filename) { return 1; }
/* encrypt.h */ #include <stdio.h> #include <stdlib.h> void encrypt_data(...); void decrypt_data(...);
/* encrypt.c */ #include "encrypt.h" void encrypt_data(...) { /* Do something */ } void decrypt_data(...) { /* Do something */ }
Flag array
/*
* Using an array to store 'flag' values
*/
#include <stdio.h>
#define BUF_SIZE 100
enum flag_t
{
APPLE,
BANANA,
CARROT,
NUM_FRUIT
};
void print_message(unsigned int flags[]);
void parse_input(char* input, unsigned int flags[]);
int main(void)
{
unsigned int flags[NUM_FRUIT];
char buf[BUF_SIZE];
printf("Input request: ");
fgets(buf, sizeof(buf), stdin);
parse_input(buf, flags);
print_message(flags);
return 0;
}
void print_message(unsigned int flags[])
{
printf("You asked for: ");
if(flags[APPLE])
printf("%d apples, ", flags[APPLE]);
if(flags[BANANA])
printf("%d bananas, ", flags[BANANA]);
if(flags[CARROT])
printf("%d carrots, ", flags[CARROT]);
printf("\n");
}
void parse_input(char* input, unsigned int flags[])
{
do
{
switch(*input)
{
case 'a':
flags[APPLE] += 1;
break;
case 'b':
flags[BANANA] += 1;
break;
case 'c':
flags[CARROT] += 1;
break;
}
} while(*++input != '\0');
}
Week 10
Assignment 1
Example solution: https://gist.github.com/3855587
Flags
/*
* Using bit fields to store 'flag' values
*
* | operator is used to set a value
* & operator is used to check a value
*/
#include <stdio.h>
#define BUF_SIZE 100
enum flag_t
{
APPLE = 1,
BANANA = 2,
CARROT = 4
};
void print_message(unsigned int flags);
unsigned int parse_input(char* input);
int main(void)
{
unsigned int flags;
char buf[BUF_SIZE];
printf("Input request: ");
fgets(buf, sizeof(buf), stdin);
flags = parse_input(buf);
print_message(flags);
return 0;
}
void print_message(unsigned int flags)
{
printf("You asked for: ");
if(flags & APPLE)
printf("apple ");
if(flags & BANANA)
printf("banana ");
if(flags & CARROT)
printf("carrot ");
printf("\n");
}
unsigned int parse_input(char* input)
{
unsigned int flags = 0;
do
{
switch(*input)
{
case 'a':
flags |= APPLE;
break;
case 'b':
flags |= BANANA;
break;
case 'c':
flags |= CARROT;
break;
}
} while(*++input != '\0');
return flags;
}
Command line
/*
* Reading values from the command line
*/
#include <stdio.h>
#include <string.h>
void print_inputs(char* str)
{
printf("You input: %s\n", str);
}
int main(int argc, char* argv[])
{
char input[200];
int i;
if(argc > 1)
{
strcpy(input, "");
for(i = 1; i < argc; i++)
{
strcat(input, argv[i]);
strcat(input, " ");
}
print_inputs(input);
}
else
{
printf("Type something: ");
fgets(input, sizeof(input), stdin);
print_inputs(input);
}
return 0;
}
File Output
/*
* Print to file and stdout from the same function
*/
#include <stdio.h>
#include <assert.h>
void print_table(FILE* fout, int rows)
{
int i;
fprintf(fout, "Header\n");
for(i = 0; i < rows; i++)
{
fprintf(fout, "Row %d\n", i);
}
}
int main(void)
{
FILE* fout;
fout = fopen("out.txt", "w");
assert(fout);
print_table(fout, 10);
print_table(stdout, 10);
fclose(fout);
return 0;
}
Week 9
Malloc
/* Week 9 Task 1
* Malloc
*/
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
int i;
int num = -1;
double *arr;
printf("Array size: ");
if(scanf("%d", &num) != 1 || num < 1)
{
printf("Input error\n");
exit(1);
}
/* Create empty array */
/*arr = (double *)malloc(num * sizeof(double));*/
arr = (double *)calloc(num, sizeof(double));
if(!arr)
{
printf("Failed to allocate memory\n");
exit(1);
}
for(i = 0; i < num; i++) {
printf("%f ", arr[i]);
}
printf("\n");
free(arr);
return 0;
}