Rishabh Ranjan
Rishabh Ranjan

Reputation: 11

String Pattern Matching in C

I was trying this pattern matching method in C but whenever I give all the input, the vscode terminal waits for a while and just stops the program without any warnings/message. Can anyone point to what is wrong here?

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

int main()
{
    char STR[100], PAT[100], REP[100], ANS[100];
    int i, m, j, k, flag, slP, slR, len;
    i = m = k = j = flag = len = 0;
    printf("\nMain String: ");
    gets(STR);
    printf("\nPattern String: ");
    gets(PAT);
    slP = strlen(PAT);
    printf("\nReplace String: ");
    gets(REP);
    slR = strlen(REP);
    while (STR[i] != '\0')
    {
        if (STR[i] = PAT[j])
        {
            len = 0;
            for (k = 0; k < slP; k++)
            {
                if (STR[k] = PAT[k])
                    len++;
            }
            if (len == slP)
            {
                flag = 1;
                for (k = 0; k < slR; k++, m++)
                    ANS[m] = REP[k];
            }
        }
        else
        {
            ANS[m] = STR[i];
            m++;
            i++;
        }
    }
    if (flag == 0)
    {
        printf("\nPattern not found!");
    }
    else
    {
        ANS[m] = '\0';
        printf("\nResultant String: %s\n", ANS);
    }
    return 0;
}

Upvotes: 1

Views: 895

Answers (1)

chqrlie
chqrlie

Reputation: 144740

There are multiple problems in the code:

  • using gets() is risky, this function was removed from the C Standard because it cannot be used safely.

  • if (STR[i] = PAT[j]) copied the pattern to the string. You should use:

      if (STR[i] == PAT[j])
    
  • similarly, if (STR[k] = PAT[k]) is incorrect. You should compare PAT[k] and STR[i + k]:

      if (STR[i + k] == PAT[k])
    
  • you should test for buffer overflow for the output string as replacing a short string by a larger one may produce a string that will not fit in ANS

  • you do not increment i properly.

Here is a modified version:

#include <stdio.h>

int getstr(const char *prompt, char *dest, int size) {
    int c, len = 0;
    printf("%s", prompt);
    while ((c = getchar()) != EOF && c != '\n') {
        if (len + 1 < size)
            dest[len++] = c;
    }
    if (size > 0)
        dest[len] = '\0';
    printf("\n");
    if (c == EOF && len == 0)
        return -1;
    else
        return len;
}

int main() {
    char STR[100], PAT[100], REP[100], ANS[100];
    int i, m, k, flag;

    if (getstr("Main String: ", STR, sizeof STR) < 0)
        return 1;
    if (getstr("Pattern String: ", PAT, sizeof PAT) < 0)
        return 1;
    if (getstr("Replace String: ", REP, sizeof REP) < 0)
        return 1;

    i = m = flag = 0;
    while (STR[i] != '\0') {
        if (STR[i] == PAT[0]) {    // initial match
            // compare the rest of the pattern
            for (k = 1; PAT[k] != '\0' && PAT[k] == STR[i + k]; k++)
                continue;
            if (PAT[k] == '\0') {  // complete match
                flag = 1;
                // copy the replacement string
                for (k = 0; REP[k] != '\0'; k++) {
                    if (m + 1 < sizeof ANS)
                        ANS[m++] = REP[k];
                }
                i += k;   // skip the matching characters
                continue;
            }
        }
        // otherwise copy a single character
        if (m + 1 < sizeof ANS)
            ANS[m++] = STR[i];
        i++;
    }
    ANS[m] = '\0';
    if (flag == 0) {
        printf("Pattern not found!\n");
    } else {
        printf("Resultant String: %s\n", ANS);
    }
    return 0;
}

Upvotes: 3

Related Questions