Skip to content

coursework/src/program.c

The original C source

All 347 lines of the submitted program, exactly as recovered. The skeleton functions came from the teaching staff; the five stages and the string comparison are mine. Every web feature on this site is a port of the functions below.

view on GitHub

/* Emoticon message cleanser: * * Skeleton code written by Farhana Choudhury and Jianzhong Qi, April 2020 * */ #include <stdio.h>#include <stdlib.h>#include <ctype.h>#include <string.h> #define STAGE_NUM_ONE 1							/* stage numbers */#define STAGE_NUM_TWO 2#define STAGE_NUM_THREE 3#define STAGE_NUM_FOUR 4#define STAGE_NUM_FIVE 5#define STAGE_HEADER "Stage %d\n==========\n"	/* stage header format string */ #define MAX_MSG_LENGTH 280						/* maximum message length */#define MAX_NUM_MSGS 100						/* maximum number of messages */#define MAX_EMTCN_LENGTH 50						/* maximum emot. line length */#define MAX_NUM_EMTCN 50						/* maximum number of emot. */ typedef char msg_t[MAX_MSG_LENGTH+1];			/* a message */typedef char emtcn_t[MAX_EMTCN_LENGTH+1];		/* an emoticon */ /****************************************************************/ /* function prototypes */void read_one_msg(msg_t one_msg, int max_len);void print_stage_header(int stage_num);int count_tokens(msg_t one_msg); void stage_one(msg_t one_msg);void stage_two(msg_t msgs[], int *num_msgs);void stage_three(msg_t msgs[], int num_msgs);void stage_four(emtcn_t emtcns[], int *num_emtcns);void stage_five(msg_t msgs[], int num_msgs, emtcn_t emtcns[], int num_emtcns); /* add your own function prototypes here */// check emotion in the dictionaryint emotionexisitence(char string1[], char string2[]); /****************************************************************/ 

main()Fixed driver: calls the five stages in order

skeleton
/* main function controls all the action, do NOT modify this function */int main(int argc, char *argv[]) {	/* to hold all input messages */	msg_t msgs[MAX_NUM_MSGS];	/* to hold the number of input messages */	int num_msgs = 0;	/* to hold all input emoticons in the dictionary */	emtcn_t emtcns[MAX_NUM_EMTCN];	/* to hold the number of emoticons in the dictionary */	int num_emtcns = 0; 	/* stage 1: reading the first message */	stage_one(msgs[num_msgs]);	num_msgs++; 	/* stage 2: removing alphanumeric characters */	stage_two(msgs, &num_msgs); 	/* stage 3: removing extra commas */	stage_three(msgs, num_msgs); 	/* stage 4: reading the dictionary and finding the longest emoticon */	stage_four(emtcns, &num_emtcns); 	/* stage 5: removing invalid emoticons with the help of the dictionary */	stage_five(msgs, num_msgs, emtcns, num_emtcns); 	/* all done; take some rest */	return 0;} 

read_one_msg()Reads one line from stdin with a length limit

skeleton
/* read a line of input into one_msg */void read_one_msg(msg_t one_msg, int max_len) {	int i = 0, c;	while (((c = getchar()) != EOF) && (c != '\n') && (c != '\r')) {		if (i < max_len) {			one_msg[i++] = c;		} else {			printf("Invalid input line, toooooooo long.\n");			exit(EXIT_FAILURE);		}	}	one_msg[i] = '\0';} 

print_stage_header()Prints the stage banner

skeleton
/* print stage header given stage number */void print_stage_header(int stage_num) {	printf(STAGE_HEADER, stage_num);} /****************************************************************/ 

count_tokens()Counts commas to count tokens

stage 1 · Count
/* scan a message and count the number of tokens (separated by commas) in it */int count_tokens(msg_t one_msg) {	int count = 0; // store number of tokens	// condition check: if a line start with commas	if (one_msg[0] == ',') {		for (int i = 0; i < MAX_EMTCN_LENGTH; i++) {			if (one_msg[i] == ',') {				count++;			}		}		return count;	} // condition check: if a line does not start with commas	else {		for (int i = 0; i < MAX_EMTCN_LENGTH; i++) {			if (one_msg[i] == ',') {				count++;			}		}		return 1 + count;	}} 

stage_one()Reads the first message

stage 1 · Count
/* stage 1: reading the first message */void stage_one(msg_t one_msg) {	/* print stage header */	print_stage_header(STAGE_NUM_ONE);	/* read the first message */	read_one_msg(one_msg, MAX_EMTCN_LENGTH);	/* count and print the number of tokens */	printf("Number of tokens: %d\n", count_tokens(one_msg));	printf("\n");} 

stage_two()Reads messages and strips letters and digits

stage 2 · Strip
/* stage 2: removing alphanumeric characters */void stage_two(msg_t msgs[], int *num_msgs) {	/* print stage header */	print_stage_header(STAGE_NUM_TWO);	/* hold temporary msgs */	msg_t tmp_msgs[MAX_NUM_MSGS];	/* start read message & stop while meet the break line */  for (int i = 1; i < MAX_NUM_MSGS; i++) {  	read_one_msg(tmp_msgs[*num_msgs], MAX_MSG_LENGTH);		if (strcmp(tmp_msgs[*num_msgs], "###") == 0) {			break;			}		/* if not meet the break line, update the line */		strcpy(msgs[*num_msgs], tmp_msgs[*num_msgs]);		*num_msgs = *num_msgs + 1;  }	/* create a new 2D array to store lines without alphanumeric characters */	msg_t remove_alphanum[MAX_NUM_MSGS];	for (int i = 0; i < *num_msgs; i++) {		int count = 0; // string index in 2D array with index[i]    int lenstr = strlen(msgs[i]); // current string length		for (int j = 0; j < lenstr; j++) {			// append the punctuation			if (ispunct(msgs[i][j])) {				remove_alphanum[i][count] = msgs[i][j];				count++;			}		}		// update new string;		strcpy(msgs[i], remove_alphanum[i]);	}	/* print out the outcome */	for (int i = 0; i < *num_msgs; i++) {		printf("%s\n", msgs[i]);	}	printf("\n");} 

stage_three()Removes leading, trailing and repeated commas

stage 3 · Commas
/* stage 3: removing extra commas */void stage_three(msg_t msgs[], int num_msgs) {	/* print stage header */	print_stage_header(STAGE_NUM_THREE);	// create a temporary 2D array to store new string without extra commas	msg_t tmp_msgs[num_msgs];	for (int i = 0; i < num_msgs; i++) {		int start = 1; // condition start as a new line		int count = 0; // index of a string where string is 2D array[i]		int lenstr = strlen(msgs[i]);		for (int j = 0; j < lenstr; j++) {			// remove the commas before the first characters			if (start == 1 && msgs[i][j] != ',') {				tmp_msgs[i][count] = msgs[i][j];				count++; // index of 2D array [i]				start = 0; // while meet the first character			} else {				// append all characters				if (msgs[i][j] != ',') {					tmp_msgs[i][count] = msgs[i][j];					count++;				// append commas if the next item is a character not a punctuation				// && not the end of the string				} else if (count != 0 && tmp_msgs[i][count - 1] != ','													    && msgs[i][j + 1] != ','													    && (j != lenstr - 1)) {					tmp_msgs[i][count] = msgs[i][j];					count++;				}			}		}		tmp_msgs[i][count] = '\0';	}	// update new string into msgs	for (int i = 0; i < num_msgs; i++) {		strcpy(msgs[i], tmp_msgs[i]);		printf("%s\n", msgs[i]);	}	printf("\n");} 

stage_four()Reads the dictionary and finds the longest emoticon

stage 4 · Dictionary
/* stage 4: reading the dictionary and finding the longest emoticon */void stage_four(emtcn_t emtcns[], int *num_emtcns) {	/* print stage header */	print_stage_header(STAGE_NUM_FOUR);	// create temporary list to store emotion	emtcn_t tmp_emtcns[MAX_EMTCN_LENGTH];	for (int i = 0; i < MAX_EMTCN_LENGTH; i++) {		// read emotion and update to temporary emotion list		read_one_msg(tmp_emtcns[*num_emtcns], MAX_EMTCN_LENGTH);		// break while meet the EOF		if (strcmp(tmp_emtcns[*num_emtcns], "") == 0) {			break;		}		*num_emtcns = *num_emtcns+1;	}	// remove commas and characters	for (int i = 0; i <* num_emtcns; i++) {		int isComma = 0, lenstr = strlen(tmp_emtcns[i]);		for (int j = 0;j < lenstr; j++) {			// condition check the current character			if (tmp_emtcns[i][j] == ',') {				isComma = 1;			}			// stop append while meet commas			if (isComma == 0) {				emtcns[i][j] = tmp_emtcns[i][j];			}		}	}	int longEmotionLen = 0, emotionIndex = 0;	/* find the longest emotion */	for (int i = 0; i <* num_emtcns; i++) {        int lenstr = strlen(emtcns[i]);		if (lenstr > longEmotionLen) {			emotionIndex = i;			longEmotionLen = strlen(emtcns[i]);		}	}	printf("Emoticon total: %d\n", *num_emtcns);	printf("Longest: %s\n", emtcns[emotionIndex]);	printf("Length: %d\n", longEmotionLen);	printf("\n");} 

emotionexisitence()Hand-written string equality (no string.h)

stage 5 · Validate
// check in emtion in the dictionaryint emotionexisitence(char string1[], char string2[]){	int i = 0, issame = 0;	while (string1[i] != '\0' && string2[i] != '\0') {		if (string1[i] != string2[i]) {			issame = 1;			break;		}		i++;	}	if (issame == 0 && string1[i] == '\0' && string2[i] == '\0') {		return 1;	} else {		return 0;	}} 

stage_five()Tokenises messages and drops unknown emoticons

stage 5 · Validate
/* stage 5: removing invalid emoticons with the help of the dictionary */void stage_five(msg_t msgs[], int num_msgs, emtcn_t emtcns[], int num_emtcns) {	/* print stage header */	print_stage_header(STAGE_NUM_FIVE);	// a new list to store word in msgs[]	char list[MAX_NUM_EMTCN][MAX_EMTCN_LENGTH];	// count the number of emotions in emotion list	int count = 0;	// state the position and string index of each emotion in msgs[]	int node = 0, index = 0;	for (int i = 0; i < num_msgs; i++) {    int strlength = 0;		// gain the length of each string		for (int k = 0; k < MAX_MSG_LENGTH; k++) {			if (msgs[i][k] == '\0') {				break;			} strlength++;		}		// separating emotion in msgs[] into a new list		for (int j = 0; j < strlength; j++) {				if (msgs[i][j] != ',') {					list[node][index] = msgs[i][j];					index++;				} else if (msgs[i][j] == ',') {					list[node][index]='\0'; 					node++;					count++;					list[node][0]=',';					list[node][1]='\0';					index=0;					node++;					count++;				}				if (j == strlength - 1) {					list[node][index]='\0';					node++;					count++;					list[node][0] = '\n';					list[node][1] = '\0';					node++;					index=0;					count++;				}			}	}	// record last emotion comparison status	int lastemtionrecord = 0;	// comparing each emotion with emotion dictionary	for (int i = 0; i < count-1; i++) {		int isEmotion = 0;		for (int j = 0; j < num_emtcns; j++) {			// condition: word is in emotion dictionary			if (emotionexisitence(list[i], emtcns[j]) == 1 ||			    list[i][0] == ',') {				isEmotion =1;			}		}		// print the results		if (isEmotion == 1 && list[i][0] != '\n') {			printf("%s", list[i]);		}		if (list[i][0] == '\n' && lastemtionrecord == 1) {			printf("\n");		}		lastemtionrecord = isEmotion;	}	printf("\n");}