Reputation: 2076
I'm trying to count words occurrence in a string. For a string S, I need to show each word and how many times this word is present in the string.
Exemple:
string = ";! one two, tree foor one two !:;"
Result:
one: 2
two: 2
tree: 1
foor: 1
Here is my code but it's not returning the right count:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int count_word(char * mot, char * text) {
int n = 0;
char *p;
p = strstr(text, mot);
while (p != NULL) {
n++;
p = strstr(p + 1, mot);
}
return n;
}
void show_all_words(char * text) {
char * p = strtok(text, " .,;-!?");
while (p != NULL) {
printf ("%s : %d\n", p, count_word(p, text));
p = strtok(NULL, " .,;-!?");
}
}
int main(char *argv[]) {
char text[] = ";! one two, tree foor one two !:;";
show_all_words(&text);
return (EXIT_SUCCESS);
};
it's returning:
one : 1
two : 0
tree : 0
foor : 0
one : 1
two : 0
: : 0
Upvotes: 3
Views: 5682
Reputation: 28310
The function strtok
changes its parameter. You can fix the problem by duplicating the string, calling strtok
on one copy and count_word
on the other.
Also, take a precaution not to output the count for the same word twice.
int count_word(char * mot, char * text, int offset) {
int n = 0;
char *p;
p = strstr(text, mot);
assert(p != NULL);
if (p - text < offset)
return -1; // if the word was found at an earlier offset, return an error code
while (p != NULL) {
n++;
p = strstr(p + 1, mot);
}
return n;
}
void show_all_words(char * text) {
char *text_rw = strdup(text); // make a read-write copy to use with strtok
char * p = strtok(text_rw, " .,;-!?");
while (p != NULL) {
int offset = p - text; // offset of the word inside input text
int count = count_word(p, text, offset);
if (count != -1) // -1 is an error code that says "already looked at that word"
printf ("%s : %d\n", p, count );
p = strtok(NULL, " .,;-!?");
}
free(text_rw); // delete the copy
}
Upvotes: 3
Reputation: 658
You should change the approach. You could use an array to store the index of first appearance of each word and the count of appearance. Only one travel in string but more travels in auxiliary array to check if the current word was already counted.
I hope is useful for you.
Upvotes: 1