Skip to content

Instantly share code, notes, and snippets.

@assyrianic
Last active November 11, 2023 19:17
Show Gist options
  • Save assyrianic/62171861d0737d165028a50735255877 to your computer and use it in GitHub Desktop.
Save assyrianic/62171861d0737d165028a50735255877 to your computer and use it in GitHub Desktop.
packs an "array" of strings into a flattened string "array" with supporting offset array to get each string.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
/**
* returns a string that contains multiple strings.
* 'offsets' is used to store the offset of each string.
* 'len' is the number of strings and offsets written.
*/
char *new_flat_string(size_t **offsets, size_t *len, ...) {
va_list args; va_start(args, len);
/// first run: collect total length.
size_t total_len = 0;
size_t count = 0;
for(;;) {
char const *sub = va_arg(args, char const*);
if( sub==NULL ) {
break;
}
total_len += (strlen(sub) + 1);
++count;
}
*len = count;
va_end(args);
/// next, allocate our buffers and then fill in 'buf'.
char *buf = calloc(total_len, sizeof *buf);
if( buf==NULL ) {
return NULL;
}
*offsets = calloc(*len, sizeof **offsets);
if( *offsets==NULL ) {
free(buf);
return NULL;
}
va_list reads; va_start(reads, len);
char *iter = buf;
size_t offs = 0;
for( size_t i=0; i < *len; i++ ) {
char const *sub = va_arg(reads, char const*);
if( sub==NULL ) {
break;
}
strcat(iter, sub);
(*offsets)[i] = offs;
size_t const n = strlen(sub) + 1;
offs += n;
iter += n;
}
va_end(reads);
return buf;
}
@assyrianic
Copy link
Author

Example Usage:

int main() {
    size_t *idxs = NULL;
    size_t len = 0;
    char *strs = new_flat_string(&idxs, &len, "first", "second", "third", "1", "keks", NULL);
    for( size_t i=0; i < len; i++ ) {
        printf("%zu : '%s'\n", i, &strs[idxs[i]]);
    }
    free(idxs); idxs = NULL;
    free(strs); strs = NULL;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment