Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Split and Join strings in C Language

Tags:

c

I learnt C in uni but haven't used it for quite a few years. Recently I started working on a tool which uses C as the programming language. Now I'm stuck with some really basic functions. Among them are how to split and join strings using a delimiter? (I miss Python so much, even Java or C#!)

Below is the function I created to split a string, but it does not seem to work properly. Also, even this function works, the delimiter can only be a single character. How can I use a string as a delimiter?

Can someone please provide some help?

Ideally, I would like to have 2 functions:

//  Split a string into a string array
char** fSplitStr(char *str, const char *delimiter);

//  Join the elements of a string array to a single string
char* fJoinStr(char **str, const char *delimiter);

Thank you,

Allen

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

char** fSplitStr(char *str, const char *delimiters)
{
    char * token; 
    char **tokenArray;
    int count=0;
    token = (char *)strtok(str, delimiters); // Get the first token
    tokenArray = (char**)malloc(1 * sizeof(char*));

    if (!token) {       
        return tokenArray;  
} 

    while (token != NULL ) { // While valid tokens are returned     
        tokenArray[count] = (char*)malloc(sizeof(token));
        tokenArray[count] = token;
        printf ("%s", tokenArray[count]);    
        count++;
        tokenArray = (char **)realloc(tokenArray, sizeof(char *) * count);      
        token = (char *)strtok(NULL, delimiters); // Get the next token     
} 
    return tokenArray;
}

int main (void)
{
    char str[] = "Split_The_String";
    char ** splitArray = fSplitStr(str,"_");
    printf ("%s", splitArray[0]);
    printf ("%s", splitArray[1]);
    printf ("%s", splitArray[2]);
    return 0;
}

Answers: (Thanks to Moshbear, Joachim and sarnold):

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

char** fStrSplit(char *str, const char *delimiters)
{
    char * token; 
    char **tokenArray;
    int count=0;
    token = (char *)strtok(str, delimiters); // Get the first token
    tokenArray = (char**)malloc(1 * sizeof(char*));
    tokenArray[0] = NULL;
    if (!token) {       
        return tokenArray;  
    } 
    while (token != NULL) { // While valid tokens are returned
        tokenArray[count] = (char*)strdup(token);
        //printf ("%s", tokenArray[count]);
        count++;
        tokenArray = (char **)realloc(tokenArray, sizeof(char *) * (count + 1));
        token = (char *)strtok(NULL, delimiters); // Get the next token
    }
    tokenArray[count] = NULL;  /* Terminate the array */
    return tokenArray;
}

char* fStrJoin(char **str, const char *delimiters)
{
    char *joinedStr;
    int i = 1;
    joinedStr = realloc(NULL, strlen(str[0])+1);
    strcpy(joinedStr, str[0]);
    if (str[0] == NULL){
        return joinedStr;
    }
    while (str[i] !=NULL){
        joinedStr = (char*)realloc(joinedStr, strlen(joinedStr) + strlen(str[i]) + strlen(delimiters) + 1);
        strcat(joinedStr, delimiters);
        strcat(joinedStr, str[i]);
        i++;
    }
    return joinedStr;
}


int main (void)
{
    char str[] = "Split_The_String";
    char ** splitArray = (char **)fStrSplit(str,"_");
    char * joinedStr;
    int i=0;
    while (splitArray[i]!=NULL) {
        printf ("%s", splitArray[i]);
        i++;
    }
    joinedStr = fStrJoin(splitArray, "-");
    printf ("%s", joinedStr);
    return 0;
}
like image 323
Allen Avatar asked Jun 24 '26 05:06

Allen


1 Answers

Use strpbrk instead of strtok, because strtok suffers from two weaknesses:

  • it's not re-entrant (i.e. thread-safe)
  • it modifies the string

For joining, use strncat for joining, and realloc for resizing. The order of operations is very important.

Before doing the realloc;strncat loop, set the 0th element of the target string to '\0' so that strncat won't cause undefined behavior.

like image 60
moshbear Avatar answered Jun 26 '26 18:06

moshbear