I wrote a function that joins a collection of Strings with a delimiter. It's based on Java's version of the function. I'm assuming C has some similar built-in.
Example:
int main() {
char* coll[] = {"Hello", "World", "This", "Should", "Be", "Joined!"};
char* joined = awfulJoinStr(", ", coll, 6);
printf("%s\n", joined);
// Prints "Hello, World, This, Should, Be, Joined!"
}
Basically how it works is, it alternates between iterating the collection strings and the delimiter. It writes the current word to the buffer until it hits a null terminator, then it switches to either writing the next word, or to the delimiter.
I'm new to C, so I'd like comments on anything in the code. My main concerns:
It's super inefficient. All the strings need to be iterated at the start to get a total length so I know how big of a buffer to allocate later. I can't see how else I'd do it though unless I do reallocations while writing, but that seems like it would be even more inefficient.
It requires three iteration counters (
stringI
,charI
, andbufferI
) and a flag. I need to keep track of the current word that I'm writing, my position in it, and need to track where I am in the buffer. I also need a flag to track when I'm currently writing a delimiter or word.It requires passing in how many strings I want to join (
nStrings
). This seems like it's necessary as well since I can't know the length ofstrArr
, but it's unfortunate.It's huge. It doesn't fit in one screen at a comfortable zoom.
I also included my version of strlen
for kicks, and because I used it instead of the built-in.
#include <stdlib.h>
#include <stdbool.h>
size_t myStrLen(char* str) {
size_t length = 0;
while (str[length] != '\0') {
length++;
}
return length;
}
char* awfulJoinStr(char* delimiter, char** strArr, size_t nStrings) {
size_t delimiterSize = myStrLen(delimiter);
size_t totalDelimiterSize = (nStrings - 1) * delimiterSize;
size_t totalStringSize = 0;
for (size_t i = 0; i < nStrings; i++) {
totalStringSize += myStrLen(strArr[i]);
}
size_t bufferSize = totalDelimiterSize + totalStringSize + 1;
char* buffer = malloc(sizeof(char) * bufferSize);
buffer[bufferSize - 1] = '\0';
bool inDelim = false;
size_t charI = 0;
size_t stringI = 0;
for (size_t bufferI = 0; bufferI < bufferSize - 1;) {
char current = inDelim ? delimiter[charI] : strArr[stringI][charI];
if (current == '\0') {
// Start at the beginning of the word and toggle what we're writing
charI = 0;
if (!inDelim) {
stringI++;
}
inDelim = !inDelim;
} else {
buffer[bufferI] = current;
charI++;
bufferI++;
}
}
return buffer;
}