0

My goal is to recreate strstr in a C function named myStrStr that returns a 1 if the substring is found in the haystack and a 0 if it is not, all while copying the matched substring into a buffer.

I tried writing the following code to solve this, and I'm unsure of why it doesn't produce the desired result when it is compiled and run.

int myStrStr(char *haystack, char *needle, char *buffer) {
    int i = 1;
    char *k = (haystack + i);
    for (; *haystack != '\0'; haystack++) {
        if (*haystack == *needle) {
            buffer[0] = *haystack;
            for (; *needle != '\0'; needle++) {
                if (*needle = *k) {
                    buffer[i] = *k;
                    i++;
                    printf("%d\n", i);
                } else
                if (strlen(buffer) == strlen(needle)) {
                    return 1;
                } else {
                    buffer[0] = 0;
                }
            }
        }
    }
    return 0;
}

an example of the driver code is as follows:

int myStrStr(char[], char[], char[]);

char haystack[][20] = { "chocolate", "vanilla", "caramel", "strawberry", "banana", "cherry" };
    char needle[][20] = { "choc", "lla", "am", "strawberry", "na", "terrible" };
    char buffer[255];

printf("\n\t=========Test #1: myStrStr with '%s' and substring '%s'===========\n\n", haystack[0], needle[0]);
int result = myStrStr(haystack[0],needle[0],buffer);
assert(result == 1&& strcmp(needle[0], buffer) == 0);
printf("\n\t\t....Test Passed\n");

printf("\n\t=========Test #2: myStrStr with '%s' and substring '%s'===========\n\n", haystack[1], needle[1]);
result = myStrStr(haystack[1],needle[1],buffer);
assert(result == 1 && strcmp(needle[1], buffer) == 0);
printf("\n\t\t....Test Passed\n");

Thanks

chqrlie
  • 131,814
  • 10
  • 121
  • 189
d827
  • 79
  • 7
  • 2
    Once you increment needle, you can't try to match again. – stark Mar 06 '19 at 15:41
  • 1
    You should also get rid of the `strlen` calls from within the loop. You should be able to get the original lengths once, outside the loop, then adjust the lengths as needed inside the loop without iterating over and over. – Tom Karzes Mar 06 '19 at 15:42
  • 1
    What's the point for `buffer`? Consider for a moment why `strstr` doesn't need one? – Antti Haapala -- Слава Україні Mar 06 '19 at 15:50
  • @d827 `buffer` is absolutely not necessary for the driver code. If you want to recreate `strstr`the signature of `myStrStr` should be identical to the one of the original `strstr`. – Jabberwocky Mar 06 '19 at 15:59
  • 1
    @d827 for testing `myStrStr` you compare the return values of `myStrStr` to the return value of `strstr` for different testcases. – Jabberwocky Mar 06 '19 at 16:02

1 Answers1

1

The function is broken in multiple ways.

Here is a corrected version:

int myStrStr(const char *haystack, const char *needle, char *buffer) {
    if (*needle == '\0') {
        /* special case for empty needle: return success with an empty match */
        buffer[0] = '\0';
        return 1;
    }
    for (; *haystack != '\0'; haystack++) {
        if (*haystack == *needle) {
            buffer[0] = *haystack;
            for (size_t i = 1;; i++) {
                buffer[i] = needle[i];
                if (needle[i] == '\0')
                    return 1;
                if (needle[i] != haystack[i])
                    break;
            }
        }
    }
    buffer[0] = '\0';
    return 0;
}

Note that copying the matched string while you scan is unnecessary, it would be sufficient to copy the needle once a match is found. As a matter of fact, the contents of buffer is either an empty string or a copy of needle: not a very useful side effect.

chqrlie
  • 131,814
  • 10
  • 121
  • 189