0

I have a long string and I want to take specific substrings of it and store it into an array of strings. I tried using malloc() with memcpy() but it doesn't seem to work. how would I go about doing this? code:

for(i = 0; i < strlen(p); i++){
        if(p[i] == ':'){
            cnt++;
            end = i - start;
            list[i] = malloc(1000);
            memcpy( list[i], &p[start], end );
            list[i][end] = '\0';
            //printf("%s\n", list[i]);
            start = i + 1;
        }
    }
reader
  • 496
  • 2
  • 15
Daniel Cook
  • 1,856
  • 8
  • 23
  • 28
  • 1
    Post the code that does not *work*. – chqrlie Mar 22 '15 at 20:33
  • 1
    Related: https://stackoverflow.com/questions/26378781/c-program-to-extract-different-substrings-from-array-of-strings?rq=1 – reader Mar 22 '15 at 20:34
  • You can use [algorithm library](http://www.cplusplus.com/reference/algorithm/) functions. – Abozanona Mar 22 '15 at 20:39
  • 1
    @YazanWYusuf That is C++, note the tags. – reader Mar 22 '15 at 20:40
  • 2
    What are you trying to do? Do you want to split the string on colons? You use the index `i` for both the char buffer and the substrings, which is certainly wrong. If you know the length of your substring, there's no need to guess the allocated memory to 1000; use `malloc(end + 1)`. Finally, do you really need copies? There might be an easier way to do what you want, for example `strtok`. – M Oehm Mar 22 '15 at 20:48
  • 1
    I assume you mean list[**count**] = malloc(1000), didn't you? The *count*th substring? Same with all `i` indices in the loop. – Peter - Reinstate Monica Mar 22 '15 at 20:48
  • need to initialize 'start' to 0 need to initialize 'cnt' to 0 – user3629249 Mar 22 '15 at 20:56

3 Answers3

1

One solution could be to use strtok, strncpy, realloc functions. For example:

int main(void){
    char str[] = "asbd0:sdsd1:ssdwdwd2";
    int tokens = 0;
    int i = 0;
    char **res = NULL;

    char *token = strtok(str, ":");
    for (tokens = 1; token; ++tokens) {
        res = realloc(res, tokens *sizeof(*res));       
        res[tokens - 1] = malloc(strlen(token) + 1);
        strncpy(res[tokens - 1], token, strlen(token) + 1);
        token = strtok(NULL, ":");
    }

    for (i = 0; i<tokens-1; ++i){
        puts(res[i]);
    }
    return 0;
}

This way we expand our "array of strings" as needed every time we find another : delimited string.

(coliru)

Scis
  • 2,934
  • 3
  • 23
  • 37
1
int len   = 0;
int start = 0;
int cnt   = 0;

for( = 0; i < strlen(p); i++)
{       
    if(p[i] == ':')
    { // then, found delimeter
        len = i - start+1;
        list[cnt] = malloc(len);
        memset( list[cnt],'\0', len );
        memcpy( list[cnt], &p[start], len );

        //printf("%s\n", list[i]);
        start = i + 1;
        cnt++;
    } // end if
} // end for
user3629249
  • 16,402
  • 1
  • 16
  • 17
0

I suggest you to use strtok or better strtok_r. Use them like this.

char *str = "Hello you new guy";
char *temp;
temp = strtok(str," ");
while(temp!=NULL) {
    printf("%s\n",temp);
    temp = strtok(NULL," ");
}

Be careful!strtok is destructive. Use strtok_r instead :

Just like strtok, this function splits the string into several tokens which can be accessed by successive calls to strtok_r. The difference is that the information about the next token is stored in the space pointed to by the third argument, save_ptr, which is a pointer to a string pointer. Calling strtok_r with a null pointer for newstring and leaving save_ptr between the calls unchanged does the job without hindering reentrancy.