find the count of substring in string
Solution 1
You could do something like
int count = 0;
const char *tmp = myString;
while(tmp = strstr(tmp, string2find))
{
count++;
tmp++;
}
That is, when you get a result, start searching again at the next position of the string.
strstr() doesn't only work starting from the beginning of a string but from any position.
Solution 2
Should already processed parts of the string should be consumed or not?
For example, what's the expect answer for case of searching oo
in foooo
, 2 or 3?
If the latter (we allow substring overlapping, and the answer is three), then Joachim Isaksson suggested the right code.
-
If we search for distinct substrings (the answer should be two), then see the code below (and online example here):
char *str = "This is a simple string"; char *what = "is"; int what_len = strlen(what); int count = 0; char *where = str; if (what_len) while ((where = strstr(where, what))) { where += what_len; count++; }
Solution 3
The results can be different depending whether you allow an overlap or not:
// gcc -std=c99
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
static int
count_substr(const char *str, const char* substr, bool overlap) {
if (strlen(substr) == 0) return -1; // forbid empty substr
int count = 0;
int increment = overlap ? 1 : strlen(substr);
for (char* s = (char*)str; (s = strstr(s, substr)); s += increment)
++count;
return count;
}
int main() {
char *substrs[] = {"a", "aa", "aaa", "b", "", NULL };
for (char** s = substrs; *s != NULL; ++s)
printf("'%s' -> %d, no overlap: %d\n", *s, count_substr("aaaaa", *s, true),
count_substr("aaaaa", *s, false));
}
Output
'a' -> 5, no overlap: 5
'aa' -> 4, no overlap: 2
'aaa' -> 3, no overlap: 1
'b' -> 0, no overlap: 0
'' -> -1, no overlap: -1
Jordan Borisov
Java developer from Bulgaria profile for Jordan Borisov at Stack Overflow, Q&A for professional and enthusiast programmers http://stackoverflow.com/users/flair/283114.png?theme=clean
Updated on February 09, 2020Comments
-
Jordan Borisov over 4 years
I have to find the count of a substring in a string using the C language. I'm using the function
strstr
but it only finds the first occurrence.My idea of the algorithm is something like searching in the string while
strstr
does not return null and to substring the main string on each loop. My question is how to do that? -
Dave over 12 yearsIf they need to be distinct substrings, you might consider
count+=strlen(string2find)
-
Johan Lundberg over 12 yearsEdit, I added protection against problems in case of string2find=""
-
Johan Lundberg over 12 years@Dave, beware of infinite loop for ""
-
Isaac Baker over 7 years@Dave and future readers, I believe you meant
tmp += strlen(string2find)
. In your example, you are incrementing the number of occurrences by the length of the string! -
melpomene almost 7 yearsDon't use global variables for no reason.
void main
is wrong; should beint main
."%[^\n]s"
doesn't do what you want; thes
is not part of the%
directive and requires a literals
to be entered. You didn't specify an upper bound for inputs; this is a potential buffer overflow. Always check the return value ofscanf
if you have to use it. Don't usescanf
for user input.strlen
returnssize_t
, notint
. You have redundant parentheses in thewhile
condition; while not a bug per se, this silences the warning gcc would give you if you typo'd==
as=
. -
melpomene almost 7 yearsThe
while
loop doesn't check for end-of-string and can run off the end ofstr
andsub
if all characters match.j
andcount
are always set together; they're effectively the same variable. Your algorithm is completely broken: It doesn't find e.g."ab"
in"aab"
. -
melpomene almost 7 yearsIn general, avoid posting answers that consist of code only. A description of the algorithm or an explanation of how your answer is different from the others would help.
-
A.B. over 4 yearsif you are finding "zz" in "zzzz" it would return 3 and (with tmp++) I believe this is correct answer, if you do something like tmp += strlen(string2find) this would just return with 2.