countSH
counts the number of occurrences of the word in the file depending on the first character of the line.
I also have a function to get the user input.
I wrote them separately and when I tested the functions individually they all worked fine.
#include <stdio.h>
#include <string.h>
int *countSH(char *filename, char *SentWord) {
//opening file and checking whether it opens
FILE *file = fopen(filename, "r");
if (file == NULL) {
perror("error while opening file");
return NULL;
}
char line[500]; //line lenght = 500
int hams = 0;
int spams = 0;
char *token = NULL;
const char *word = SentWord;
char *lineDupe;
while(1) {
if (feof(file)) {
break; //breaking the loop when getting to the end of the file
}
if (fgets(line, sizeof(line), file) != NULL) { //if line != NULL
lineDupe = strdup(line);
token = strtok(lineDupe, " \t\n");
while (token != NULL) {
if (strcmp(token, word) == 0) {
if (line[0] == 'h') { //if line starts with h (ham)
hams++;
} else { //else it starts with s (spam)
spams = spams + 1;
}
}
token = strtok(NULL, " \t\n");
}
}
}
int countsh[2] = { hams, spams };
if (hams == 0 && spams == 0) {
printf("This word doesn’t occur in the text!");
} else {
printf("The word '%s' appears %d times in ham messages and %d times in spam messages.");
}
return countsh;
}
//this function gets the user input and saves the word for searching
char *getWord() {
static char word[256];
printf("Please enter a word to search for:\t");
scanf("%255s", word);
return word;
}
int main() {
char *searchWord = getWord(); //assigning the searchword we got from the user to a var
char *file = "preprocessed_dataset.txt";
int *word_in_sh = countSH(file, searchWord);
return 0;
}
the only warning is this and I really don't get what the problem
try1_3.c: In function ‘countSH’:
try1_3.c:50:2: warning: function returns address of local variable [-Wreturn-local-addr]
return countsh;
The statement return countsh;
returns the address of the array countsh
to the caller, yet this array is defined as a local object with automatic storage, hence it becomes invalid as soon as the function returns. This is a real problem as the caller cannot read the values from this array reliably.
You can fix this:
static
object, but this would be a quick and dirty fix with other side effects, for example if you call countSH
multiple times, the intermediary results will be overwritten by the next call.Note these further remarks:
you allocate a copy of each line read with strdup(line)
but you do not free these clocks, causing systematic memory leaks. You do not actually need to allocate memory for this task, just save the ham/spam status before the strtok
loop.
the logic for the parse loop is cumbersome, the test on feof()
should be removed and the loop should be written as
while (fgets(line, sizeof(line), file)) {
/* parse the line */
}
the second printf
statement expects arguments for the search word and the counts.
the file opened in countSH
is not closed.
Here is a modified version:
#include <errno.h>
#include <stdio.h>
#include <string.h>
// count words and update counts in the destination array
// return 1 for success, 0 in case of error
int countSH(const char *filename, const char *word, int *countsh) {
//opening file and checking whether it opens
FILE *file = fopen(filename, "r");
if (file == NULL) {
fprintf(stderr, "error while opening file %s: %s\n",
filename, strerror(errno));
return 0;
}
char line[500]; //line length is 498
int hams = 0;
int spams = 0;
while (fgets(line, sizeof line, file)) {
char c0 = line[0];
char *token = strtok(line, " \t\n");
while (token != NULL) {
if (strcmp(token, word) == 0) {
if (c0 == 'h') { // if line starts with h (ham)
hams++;
} else { // else it starts with s (spam)
spams++;
}
}
token = strtok(NULL, " \t\n");
}
}
fclose(file);
countsh[0] = hams;
countsh[1] = spams;
return 1;
}
// get the user input and save the word for searching
int getWord(char *word, size_t size) {
char format[20];
snprintf(format, sizeof format, "%%%ds", (int)size);
printf("Please enter a word to search for: ");
return scanf(format, word) == 1;
}
int main(void) {
char searchWord[256];
if (!getWord(searchWord, sizeof searchWord))
return 1;
cosnt char *filename = "preprocessed_dataset.txt";
int word_in_sh[2];
if (!countSH(filename, searchWord, word_in_sh))
return 1;
if (word_in_sh[0] == 0 && word_in_sh[1] == 0) {
printf("This word doesn’t occur in the text!\n");
} else {
printf("The word '%s' appears %d times in ham messages and %d times in spam messages.\n",
searchWord, word_in_sh[0], word_in_sh[1]);
}
return 0;
}