2

I tried to implement a small splitStringByString() function in C, this is how I have come so far:

char* splitStringByString(char* string, char* delimiter){
    int i = 0, j = 0, k = 0;
    while(*(string + i) != '\0'){
        j = i;
        while((*(string + j) == *(delimiter + k)) && (*(string + j) != '\0')){
            if(*(delimiter + k + 1) == '\0'){
                // return string from here.
                char result[(strlen(string) - strlen(delimiter) + 1)];  // + 1 for '\0'
                i = 0;
                j++;
                while(*(string + j) != '\0'){
                    result[i] = *(string + j);
                    i += 1;
                    j++;
                }
                i = (int)strlen(result);
                result[i - 1] = '\0';
                return result;
            }
            k++;
            j++;
        }
        i++;
    }

    return NULL;
}

So it works more or less; the function returns the string after the delimiter as wanted, but at the end of this string (the last character) is always \377. I already found something that said this is an octal number or so (stackoverflow), but it is not very clear for me. Could you help me and give me some advice about what I did wrong?

Thanks a lot! :-)

j3141592653589793238
  • 1,810
  • 2
  • 16
  • 38
  • 5
    `i = (int)strlen(result); result[i - 1] = '\0';` what if string has 0 length? why null terminating a string in the middle of it? – Jean-François Fabre Aug 09 '17 at 19:33
  • what does this function actually do? What is the idea? – 0___________ Aug 09 '17 at 19:36
  • 3
    You are returning a pointer to an object on the stack - which will get overwritten. My compiler won't compile this because the definition of result cannot be allocated because the size is not constant. – Brian Walker Aug 09 '17 at 19:36
  • @PeterJ The function should split a string by a string, f.ex. splitStringByString("Hellosamigos", "llosa") should return "migos". – j3141592653589793238 Aug 09 '17 at 19:38
  • 3
    @BrianWalker you're compiling this as `C` **not** `C++` yeah? Mine seems to compile it fine. –  Aug 09 '17 at 19:39
  • @Jean-François Fabre what do you mean with terminating it in the middle? The last character should be '\0'. – j3141592653589793238 Aug 09 '17 at 19:40
  • @Thebluefish I get the compiler error for C++ or C. The problem with the code is that it is returning the address of a stack array that can be overwritten once the function returns - which would explain strange characters showing up in the data. – Brian Walker Aug 09 '17 at 19:43
  • 3
    `i = (int)strlen(result)`: if the last character isn't 0 then `strlen` doesn't work... – Jean-François Fabre Aug 09 '17 at 19:43
  • 2
    @Jean-FrançoisFabre Well that's absolutely true, haven't thought about it.Thanks! – j3141592653589793238 Aug 09 '17 at 19:46
  • 3
    @BrianWalker: C.1999 has a feature called VLA (variable length array). Not all compilers are C.1999 compliant. C.2011 made VLA an optional feature. – jxh Aug 09 '17 at 19:56

1 Answers1

2

I do not understand your code but to do what you mention in the comment

char *splitSstring(char *haystack, char *separator)
{
    char *result = (haystack == NULL || separator == NULL || !strlen(haystack) || !strlen(separator)) ? NULL : haystack;

    if (result != NULL)
    {
        result = strstr(haystack, separator);
        if (result != NULL) result += strlen(separator);
    }
    return result;
}

or if you want to have it in the separate string

char *splitSstring(char *haystack, char *separator, char *res)
{
    char *result = (haystack == NULL || separator == NULL || !strlen(haystack) || !strlen(separator)) ? NULL : haystack;

    if (result != NULL)
    {
        result = strstr(haystack, separator);
        if (result != NULL)
        {
            result = result + strlen(separator);
            if(res == NULL) res = malloc(strlen(result) + 1);
            if(res != NULL) strcpy(res, result);
            result = res;
        }
    }
    return result;
}

you can provide your own buffer to the function or if you pass NULL it will be allocated for you. But you need to remember to free it;

0___________
  • 60,014
  • 4
  • 34
  • 74
  • That's basically it ;-) Didn't remember that strstr does not only return NULL if a string is not found but also the exact position otherwise. Thanks a lot. Why don't you understand my code and do you know what I did wrong? – j3141592653589793238 Aug 09 '17 at 19:53
  • 1
    @T.Meyer: In your code, you return `result`, which is a local array. When an array name is used in most expressions, the name decays to the address of the first array member. Thus, your code returns the address of a object that was local to the function. However, a local object become invalid once it is no longer in scope. Retuning from a function invalidates all of its local objects. When you return a value from a `int` variable, you get a copy of the value, but you don't get that behavior from arrays. – jxh Aug 09 '17 at 20:03
  • 1
    @T.Meyer - my advice - try to split problems into a smaller bits. Write function which will find the occurrence of one string in another - it is easier and separates the logic. Then having this one it is extremely easy to sort out your problem. Having to sort out both puzzles you just got lost. – 0___________ Aug 09 '17 at 20:10
  • 1
    @T.Meyer you do not have any memory leaks as you do not allocate any memory. Memory leak is if memory is allocated but not freed and it gets lost to the program / system. You just have a lots of UBs (like returning pointers to not existing objects, strlen-ing the not null terminated memory locations, then writing something to the memory in the random locations etc) – 0___________ Aug 09 '17 at 20:18