i,m trying to write this code, it should counting the number of substring, which are not including in the string, for examples(below), in the main i was trying with pointer to work with String without using arrays but it didnt work at all!!
// count_target_string("abc of", "of") -> 1
// count_target_string("abcof", "of") -> 0
// count_target_string("abc of abc of", "of") -> 2
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int countTargetString(char* text , char* string){
char d[]=" ";
char * portion = strtok(text,d);
int result=0;
while (portion!=NULL){
if (strcmp(portion,string)==0){
result ;
}
portion = strtok(NULL,d);
}
return result;
}
int main(){
printf("%d\n",countTargetString("abc of abc of","of"));
char *test ="abc of abc of";
char *d = "of";
printf("%d\n",countTargetString(test,d));
return 0;
}
CodePudding user response:
strtok
modifies the string.char *test ="abc of abc of";
defines the pointer to the string literal. Modification of the string literal invokes Undefined Behaviour (UB). It is why your code does "not work at all" Same if you pass string literal reference directly to the function (ie use a string literal as a parameter)countTargetString("abc of abc of","of"));
.
Your pointer must reference a modifiable string:
int main()
{
char mystring[] = "abc of abc of";
char *test = mystring;
char *d = "of";
printf("%d\n",countTargetString(test,d));
}
CodePudding user response:
While strtok
will not work with a string literal, strspn
and strcspn
can be used.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int countTargetString(char* text , char* string){
char d[]=" ";
int result = 0;
size_t span = 0;
while ( *text) {
text = strspn ( text, d);
span = strcspn ( text, d);
if ( strncmp ( text, string, span)) {
result;
}
text = span;
}
return result;
}
int main( void) {
printf("%d\n",countTargetString("abc of abc of","of"));
char *test ="abc of abc of";
char *d = "of";
printf("%d\n",countTargetString(test,d));
return 0;
}
CodePudding user response:
In the both calls of the function countTargetString
printf("%d\n",countTargetString("abc of abc of","of"));
char *test ="abc of abc of";
char *d = "of";
printf("%d\n",countTargetString(test,d));
you are passing pointers to string literals.
Though in C opposite to C string literals have types of non-constant character arrays nevertheless you may not change a string literal. Any attempt to change a string literal results in undefined behavior.
From the C Standard (6.4.5 String literals)
7 It is unspecified whether these arrays are distinct provided their elements have the appropriate values. If the program attempts to modify such an array, the behavior is undefined.
And the function strtok
changes the source string inserting terminating zero characters '\0' to extract substrings.
It is always better even in C to declare pointers to string literals with the qualifier const
.
Instead of the function strtok
you can use function strstr
.
Here is a demonstration program.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
size_t countTargetString( const char *s1, const char *s2 )
{
size_t count = 0;
size_t n = strlen( s2 );
for ( const char *p = s1; ( p = strstr( p, s2 ) ) != NULL; p = n )
{
if ( ( p == s1 || isblank( ( unsigned char )p[-1] ) ) &&
( p[n] == '\0' || isblank( ( unsigned char )p[n] ) ) )
{
count;
}
}
return count;
}
int main( void )
{
printf("%zu\n",countTargetString("abc of abc of","of"));
const char *test ="abc of abc of";
const char *d = "of";
printf("%zu\n",countTargetString(test,d));
}
The program output is
2
2
As you can see the function parameters are also declared with the qualifier const
because the function does not change passed strings.
Pay attention to that in any case to count occurrences of substrings in a string it is a bad idea to change the original string.
CodePudding user response:
int count_substr(const char* target, const char* searched) {
int found = 0;
unsigned long s_len = strlen(searched);
for (int i = 0; target[i]; i ) {
// use memcmp to NOT compare the null terminator of searched
if (memcmp(target i, searched, s_len) == 0) {
found ;
i = s_len - 1;
}
}
return found;
}
This is a very basic implementation of substring counting. For the fastest solution possible, copy the boyer moore pattern matching algorithm from wikipedia or wherever you want and modify it to cound instead of terminationg on a match.