2

I've seen many solutions for getting substring of a string with usage of strndup or memcpy or strncpy and etc,.

I was wondering if there's a way to get substring without using those functions; even if it's unnecessary.

EDIT: I tried making function myself; I don't remember what the problem was but something went wrong and I ended up not using it.

char *substring(char *str, int start, int length) { 
    char *s = malloc(sizeof(char)*(length+1));

    for(int i=start; i<start+length; i++) {
        s[i-start] = str[i];  
    }
    s[length] = '\0';

    return s;
}
6
  • 3
    Damn near everything can be done in C with a suitably-constructed for loop. Commented Nov 24, 2014 at 5:15
  • 1
    YES! there are many way's to find substring in a string without using any of those functions Commented Nov 24, 2014 at 5:16
  • OKAY! It was just that I tried but couldn't get it working flawlessly without using those functions. Commented Nov 24, 2014 at 5:19
  • @Haxify, can you show us some code, what you have tried? Commented Nov 24, 2014 at 5:21
  • Use (char *)malloc(sizeof(char)*(length+1)); Commented Nov 24, 2014 at 5:37

2 Answers 2

3

There are a number of ways to recreate strstr. The following is a quick implementation using the inch-worm method, where you simply use pointers to search for the beginning of the substring in string, then if found, compare every character in substring with the corresponding character in string. If all characters match, the substring is found, return a pointer to the beginning of substring in string.

If a character fails the test, look for another character in string that matches the first character in substring, until string is exhausted.

There are probably several more checks that can be inplemented, but this example should get you started:

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

char *strstr2 (char *str, char *sub)
{
    if (!str || !sub) return NULL;              /* validate both strings    */

    char *p = NULL;                             /* general pointer          */
    char *sp = NULL;                            /* substring pointer        */
    char *rp = NULL;                            /* return pointer           */
    char matched = 0;                           /* matched flag             */
    size_t szstr = 0;                           /* string length            */
    size_t szsub = 0;                           /* substring length         */

    p = sub;
    while (*p++) szsub++;                       /* strlen of substr         */

    p = str;
    while (*p++) szstr++;                       /* strlen of str            */

    if (szsub > szstr) return NULL;             /* szstr < szsub - no match */

    p = str;

    while (p < (p + szstr - szsub + 1))
    {
        while (*p && *p != *sub) p++;           /* find start of sub in str */

        if ((str + szstr) == p) return NULL;    /* if end reached - no sub  */

        rp = p;                                 /* save return pointer      */
        sp = sub;                               /* set sp to sub            */
        matched = 1;                            /* presume will match       */
        while (*sp)                             /* for each in substring    */
            if (*p++ != *sp++) {                /* check if match fails     */
                matched = 0;                    /* if failed, no match      */
                break;                          /* break & find new start   */
            }
        if (matched)                            /* if matched, return ptr   */
            return rp;                          /* to start of sub in str   */
    }

    return NULL;                                /* no match, return NULL    */
}

int main() {

    char *string = NULL;
    char *substr = NULL;
    char *begin = NULL;

    printf ("\nEnter string : ");
    scanf ("%m[^\n]%*c", &string);

    printf ("\nEnter substr : ");
    scanf ("%m[^\n]%*c", &substr);

    if ((begin = strstr2 (string, substr)) != NULL)
        printf ("\nSubstring found beginning at : %s\n\n", begin);
    else
        printf ("\nSubstring NOT in string.\n\n");

    if (string) free (string);
    if (substr) free (substr);

    return 0;
}

output:

$ ./bin/strstr

Enter string : This is the full string or "haystack".

Enter substr : g or "

Substring found beginning at : g or "haystack".

$ ./bin/strstr

Enter string : This is the full string or "haystack".

Enter substr : g or '

Substring NOT in string.
Sign up to request clarification or add additional context in comments.

Comments

0

Wow!!! So many variables and tests and lots of indentation.

In the 1970's, some considered it poor style to not have all of the return statements at the bottom of the routine, but that thinking has mostly disappeared.

For some reason, many programmers write their conditionals to test if one variable is equal, not equal, greater, or less than something else. They believe that conditionals should be boolean values and nothing else. But C allows tests of int, char or others equal or not equal to zero. Zero can be NULL or NUL or any other zero value. This is legal and appropriate. if (variable) return NULL;

Some consider conditionals with side effects, such as, if (*h++ == *n++) continue; where variables h and n are modified, to not be great style. To avoid that, I suppose you can rewrite it as if (*h == *n) { h++; n++; continue;}

Here is my version. It is not worse than the version you supplied on this page. But I want to believe it is shorter, simpler, and easier to understand. My style is not perfect. Nobody has perfect style. I supply this only for contrast.

char * strstr( const char *haystack, const char *needle) {
  const char *h = haystack, *n = needle;
  for (;;) {
    if (!*n) return (char *)h;
    if (!*h) return NULL;
    if (*n++ == *h++) continue;
    h = ++haystack;
    n = needle;
  }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.