Hi! This is my first post here but I am sure not the last one hah. I am still newbie when it comes to programming - my first year learning it during studies.
The programme itself takes the every word from file and counts how often does every word occur. It works fine, but I keep on struggling to find, where are the memory leaks. I still get 106 allocs and 27 frees here.
I have to do it using linear search and the function of 'structure' type which will return structure with number of occurances of certain word and the actual word.
Sorry for messy post like this, I will make other posts more organized.
Code:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
typedef struct{
char* word;
int count;
}Structure;
Structure* words;
int arraySize;
int endOfFile;
FILE *openFile(char *fileName);
void closeFile(FILE *fp, char *fileName);
char *getWord(FILE *fp);
Structure * findWord(char* word);
int linearSearch(Structure* pointer, int size, char* find);
int main(int argc, char *argv[]) {
if(argc == 2) { /*check input syntax; requires 2 items ./name infile*/
int i = 0;
char* word;
Structure* foundWord;
FILE *input = openFile(*(argv + 1));
arraySize = 0;
word = getWord(input);
while(!endOfFile){
if (word != NULL){
foundWord = findWord(word);
if(foundWord == NULL){
arraySize++;
words = realloc(words, arraySize * sizeof(Structure));
words[i].word = malloc((strlen(word) + 1) * sizeof(char));
strcpy (words[i].word, word);
words[i].count = 1;
i++;
}else{
(*(foundWord)).count++;
}
free(word);
}
word = getWord(input);
}
free(word);
for ( i = 0 ; i < arraySize; i++ ){
printf("%s - %d\n", words[i].word, words[i].count);
}
for ( i = 0; i < arraySize; i++ ){
free( words[i].word );
}
free( words );
closeFile(input, *(argv + 1));
}
else {
printf("Incorrect invocation of %s\n", *argv);
exit(EXIT_FAILURE);
}
return 0;
}
FILE *openFile(char *fileName) { /*handles file opening*/
FILE *fp;
if((fp = fopen(fileName, "r")) == NULL) {
printf("Cannot open file: %s\n", fileName);
exit(EXIT_FAILURE);
}
else {
printf("FILE OPENED\n");
}
return fp;
}
void closeFile(FILE *fp, char *fileName) { /*handles file closing*/
if(fclose(fp) == EOF) {
printf("Error closing file: %s\n", fileName);
exit(EXIT_FAILURE);
}
else {
printf("FILE CLOSED\n");
}
}
char *getWord(FILE *fp) {
char *savedString = NULL, *tmp = NULL;
size_t size = 0, index = 0;
int scanBuffer = EOF;
while(scanBuffer) {
scanBuffer = fgetc(fp);
if (scanBuffer == EOF && savedString == NULL){
endOfFile = 1;
return NULL;
}
if(!isalpha(scanBuffer)) {
scanBuffer = 0;
break;
}
if(size <= index) {
size += sizeof(char);
if((tmp = realloc(savedString, size)) == NULL) {
printf("MEMORY ERROR\n");
}
if(!tmp) {
free(savedString);
savedString = NULL;
break;
}
savedString = tmp;
}
savedString[index++] = tolower(scanBuffer);
}
if(savedString != NULL){
size += sizeof(char);
if((tmp = realloc(savedString, size)) == NULL) {
printf("MEMORY ERROR\n");
}
if(!tmp) {
free(savedString);
savedString = NULL;
}
savedString = tmp;
savedString[index++] = '\0';
}
return savedString;
}
Structure * findWord(char* word){
int position;
position = linearSearch (words, arraySize, word);
if (position == -1){
return NULL;
}
return &words[position];
}
int linearSearch(Structure *pointer, int size, char* find){
int i;
for ( i = 0 ; i < size ; i++ ){
if (strcmp( (*(pointer + i)).word, find) == 0){
return i;
}
}
return -1;
}
Easy come, easy go, will you let me go?
Bis-mil-lah !
No, we will not let you go. (Let him go)
Bis-mil-lah !
We will not let you go. (Let me go)
Bis-mil-lah !
We will not let you go. (Let me go)
Will not let you go. (Let me go)
Will not let you go. (Let me go)
Ah.
No, no, no, no, no, no, no (Oh mamma mia, mamma mia)
Mamma mia, let me go.
Belzebub has a devil put aside for me, for me, for me.
For example for text file above you get:
FILE OPENED
easy - 2
come - 1
go - 13
will - 6
you - 6
let - 12
me - 9
bis - 3
mil - 3
lah - 3
no - 8
we - 3
not - 5
him - 1
ah - 1
oh - 1
mamma - 3
mia - 3
belzebub - 1
has - 1
a - 1
devil - 1
put - 1
aside - 1
for - 3
FILE CLOSED