Reputation: 87
I need to count how many times a smaller string is in bigger string with strstr(), and I know that when using strstr() it will put the pointer in the spot where the smaller string is found in bigger string. But I don't know what kind of a loop I should write to check that how many times this smaller string is presented in this bigger string? So in this case the correct answer would be 3.
My code:
#include <stdio.h>
#include <string.h>
int count_substr(const char *str, const char *sub) {
int i = 0;
int res;
res = strstr(str, sub);
if (res) {
i++;
}
else {
i = i;
}
return i;
}
int main(void) {
char lol[] = "one two one twotwo three";
char asd[] = "two";
int ret;
ret = count_substr(lol, asd);
printf("%d", ret);
}
Upvotes: 1
Views: 2087
Reputation: 16550
res = strstr(str, sub);
res
should be declared as char *res;
rather than int res;
because the function: strstr()
returns a char*
not a int
. This error causes the compiler to output a warning message. You should have seen that warning and corrected it before posting the question.what is this:
i = i;
the following proposed code:
And now, the proposed code:
#include <stdio.h> // printf()
#include <string.h> // strstr()
// prototypes
int count_substr( const char *str, const char *sub );
int main(void)
{
char lol[] = "one two one twotwo three";
char asd[] = "two";
int ret = count_substr( lol, asd );
printf( "%d\n", ret ); // '\n' so immediately displayed on terminal
}
int count_substr( const char *str, const char *sub )
{
int count = 0;
int index = 0;
char *oldres = NULL;
char *newres = NULL;
do
{
newres = strstr( &str[index], sub );
index++;
if( newres != oldres && newres )
count++;
oldres = newres;
} while( oldres );
return count;
}
Upvotes: 0
Reputation: 13590
You can use a while
loop like this:
int count_substr(const char *str, const char *sub) {
int cnt = 0;
char *found;
while(found = strstr(str, sub))
{
cnt++;
str = found + 1;
}
return cnt;
}
The interesting part is this:
str = found + 1;
because you are not interested in the characters before the found substring, you
can safely ignore them and advance str
to the next character after the found
substring. strstr
eventually will return NULL
when no substring is found or
when str[0] == 0
after it reaches the end of the string.
edit
I put this in the answer because the comment section is far to restricted for longer comments.
found
is a pointer to char
. Whether it's pointing to a single char
object
or to the start of a sequence of bytes or the start of a string, depends on the
context. The context here is that found
is assigned with the return value of
the function strstr
.
man strstr
#include <string.h> char *strstr(const char *haystack, const char *needle);
DESCRIPTION
The
strstr()
function finds the first occurrence of the substringneedle
in the stringhaystack
. The terminating null bytes ('\0'
) are not compared.RETURN VALUE
[This function returns] a pointer to the beginning of the located substring, or
NULL
if the substring is not found.
On success strstr
returns a pointer to the location of the source where the substring is
found. So found
will return a pointer to "two one twotwo three"
.
found + 1
is pointer arithmetic and it's the same as doing &(found[1])
which will return
a pointer to the next char
in the sequence. found + 1
will point to
"wo one twotwo three"
and this pointer it will be assigned to str
, so that
str
points to the next character after the found substring.
If I don't do
that, I would have created an endless loop, because strstr
would keep
returning the same substring, over and over.
So the next time strstr(str, sub)
is executed, found
will point to
"twotwo three"
, and found + 1
will return a pointer to "wotwo three"
, and
so on.
In case that the substring is not found, it will return NULL
the loop ends. At
that point it doesn't matter that found
is also pointing to NULL
.
Upvotes: 2
Reputation: 4454
The function strstr()
returns a char
pointer, not an int
, so the variable to be assigned its returned value should be of type char *
. You can use this value to loop over a string and find the number of sub-strings in it; A while
loop would suffice:
#include <stdio.h>
#include <string.h>
#include <stddef.h>
int count_substr(const char *str, const char *sub)
{
int i = 0;
size_t sub_len = strlen(sub);
const char *res = strstr(str, sub);
while (res)
{
i++;
str = res + sub_len;
res = strstr(str, sub);
}
return i;
}
int main(void)
{
char lol[] = "one two one twotwo three";
char asd[] = "two";
int ret = count_substr(lol, asd);
printf("ret: %d\n", ret);
return 0;
}
Upvotes: 1