How to get a substring from a string in C?

10,491
void substr(char* str, char* sub , int start, int len){
    memcpy(sub, &str[start], len);
    sub[len] = '\0';
}

int main(void)
{
    char *test = (char*)malloc(sizeof(char)*5);
    char *sub = (char*)malloc(sizeof(char)*3);
    strcpy(test, "test");
    substr(test, sub, 1, 2);

    printf("%s\n", sub); // prints "es"
    free(test);
    free(sub);

    return 0;
}
Share:
10,491
BrockLee
Author by

BrockLee

M'aggot

Updated on June 27, 2022

Comments

  • BrockLee
    BrockLee almost 2 years

    I want to create a function in C that gets the a substring from a string. This is what I have so far:

    char* substr(char* src, int start, int len){
        char* sub = malloc(sizeof(char)*(len+1));
        memcpy(sub, &src[start], len);
        sub[len] = '\0';
        return sub;
    }
    
    int main(){
        char* test = malloc(sizeof(char)*5); // the reason I don't use char* = "test"; is because I wouldn't be able to use free() on it then
        strcpy(test, "test");
        char* sub = substr(test, 1, 2); // save the substr in a new char*
        free(test); // just wanted the substr from test
        printf("%s\n", sub); // prints "es"
    
        // ... free when done with sub
        free(sub);
    }
    

    Is there any way I can save the substring into test without having to create a new char*? If I do test = substr(test, 1, 2), the old value of test no longer has a pointer pointing to it, so it's leaked memory (I think. I'm a noob when it comes to C languages.)

  • BrockLee
    BrockLee about 9 years
    Wouldn't this lead to a memory leak? Although test is pointing to a new value on the line test = substr(test, 1, 2); , the old value for test has nothing pointing to it now and I have no way of freeing it.
  • Bill Lynch
    Bill Lynch about 9 years
    You can not change the contents of a string literal!
  • Senam Tomkat
    Senam Tomkat about 9 years
    @BillLynch hope this would help... u dont need to create a new string in substr function...just memcpy it in subtr() and if you want substring in same string just pass substr(test, test, 1, 2)
  • Bill Lynch
    Bill Lynch about 9 years
    @MohsinLatif: Your edit is what I would personally prefer the interface to look like. And now it doesn't leak either :)
  • Philip
    Philip about 9 years
    It's implementation dependent! But yeah, I was probably thinking of how code-composer for the MSP430 handles it. Typically it's read-only. Good point. ADDITIONAL YELLING
  • Bill Lynch
    Bill Lynch about 9 years
    It's undefined behavior, not implementation defined behavior. C 2011 Section 6.4.5 Paragraph 7: It is unspecified whether these arrays are distinct provided their elements have the appropriate values. If the program attempts to modify such an array, the behavior is undefined.
  • Philip
    Philip about 9 years
    @BillLynch dude, are you kidding me? If some behaviour is not defined by a standard (why are you assuming C11 anyway?) but the compiler and environment allow it to happen anyway, what do you think the end results depends upon?
  • Bill Lynch
    Bill Lynch about 9 years
    The same sentence can be found in C99 Section 6.4.5 Paragraph 6 if you'd rather. I don't have a copy of C90 lying around but I imagine the same line is there as well.
  • chux - Reinstate Monica
    chux - Reinstate Monica about 9 years
    in char* sub = calloc (1, sizeof *sub + len + 1);, sizeof *sub + len + 1 seems like it should be len + 1. BTW: Could return memcpy (sub, src + start, len);.
  • chux - Reinstate Monica
    chux - Reinstate Monica about 9 years
    I'd expect strcpy(dst, src + offset, length); to take 2 arguments, not 3. Were you thinking memcpy()?
  • Bill Lynch
    Bill Lynch about 9 years
    @chux: I was thinking of something that would do more work for me :)
  • David C. Rankin
    David C. Rankin about 9 years
    Correct you are on both points. I left the return sub; rather than the return memcpy.... just because it adds another level of understanding that may be bewildering to those just learning.