timsterc
timsterc

Reputation: 1033

Number of times one string occurs within another in C

I have written a function that uses the strstr() function to determine if string2 has any matches in string1. This works fine (I also convert both strings to lower case so that I can do a case-insensitive match.). However, strstr() only finds the first time the match occurs. Is there a way to use it to find each time a match occurs? For example:

string1[] = "ABCDEFABC";
string2[] = "ABC";

Would return 0 as a match is found in position 0, and 6 as it's found again in position 6?

Here's the original function as written (including call to function in main):

#include <stdio.h>
#include <string.h>
#include <stdlib.h>



char *strstrnc(const char *str1, const char *str2);

int main()
{
    char buf1[80],buf2[80];

    printf("Enter the first string to be compared: ");
    gets(buf1);
    printf("Enter the second string to be compared: ");
    gets(buf2);

    strstrnc(buf1,buf2);

    return 0;
}


char *strstrnc(const char *buf1, const char *buf2)
{
    char *p1, *ptr1, *p2, *ptr2, *loc;
    int ctr;

    ptr1 = malloc(80 * sizeof(char));
    ptr2 = malloc(80 * sizeof(char));


    p1 = ptr1;
    p2 = ptr2;



    for (ctr = 0; ctr < strlen(buf1);ctr++)
    {
        *p1++ = tolower(buf1[ctr]);
    }
    *p1 = '\0';

    for (ctr = 0; ctr < strlen(buf2);ctr++)
    {
        *p2++ = tolower(buf2[ctr]);
    }
    *p2 = '\0';

    printf("The new first string is %s.\n", ptr1);
    printf("The new first string is %s.\n", ptr2);

    loc = strstr(ptr1,ptr2);
    if  (loc == NULL)
    {
        printf("No match was found!\n");
    }
    else
    {
        printf("%s was found at position %ld.\n", ptr2, loc-ptr1);
    }

    return loc;

}

Upvotes: 1

Views: 645

Answers (2)

Michi
Michi

Reputation: 5297

I think this is what you need:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int main(void){
    char string1[] = "ABCDABCEFABC";
    char string2[] = "ABC";
    char *s1, *s2, *s3;

    size_t lenstring1 = strlen(string1);
    size_t lenstring2 = strlen(string2);

    if (lenstring2 < 1){
        printf("There is no substring found"); /* or what ever */
        exit(1);
    }

    size_t i=0,j=0;
    int found=0;

    s1 = string1;
    s2 = string2;


    for(i = 0; i < lenstring1; i++){
        if(*s1 == *s2){
              s3 = s1;
              for(j = 0;j < lenstring2;j++){
                if(*s3 == *s2){
                  s3++;s2++;
                }else{
                    break;
                }
              }

              s2 = string2;

              if(j == strlen(string2)){
                 found = 1;
                printf("%s found at index : %zu\n",string2,i+1);
              }
          }
        s1++;
    }

    if(found == 0){
        printf("No match Found");
    }

    return 0;
}

Output:

ABC found at index : 1
ABC found at index : 5
ABC found at index : 10

If the string2 is empty you will get:

There is no substring found

Upvotes: 2

R Sahu
R Sahu

Reputation: 206607

Given

char string1[] = "ABCDEFABC";
char string2[] = "ABC";

strstr(string1, string2) will return a pointer to the first element of string1.

Would return 0 as a match is found in position 0, and 6 as it's found again in position 6?

In order to check for multiple occurrences of string2 in string1, you'll have to call strstr multiple times with an offset from string1. E.g.

char* found = strstr(string1, string2);
while ( found != NULL )
{
   // Search for string2 after applying an offset.
   int offset = 1;
   found = strstr(found+offset, string2);
}

Upvotes: 3

Related Questions