Skip to content

Instantly share code, notes, and snippets.

@opsJson
Last active December 25, 2021 23:26
Show Gist options
  • Select an option

  • Save opsJson/d50bbc9adb1c122045b982350ea09b88 to your computer and use it in GitHub Desktop.

Select an option

Save opsJson/d50bbc9adb1c122045b982350ea09b88 to your computer and use it in GitHub Desktop.
Easily allocate a list of any amount of strings.
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
size_t counter(char *str) {
size_t commas = 0;
int string = 0;
while (*str) {
//escape commas inside string;
if (*str == '"' && *(str - 1) != '\\') string = !string;
//count commas
if (string == 0)
if (*str == ',') commas++;
str++;
}
return commas+1;
}
#define s_list(...) _s_list(counter(#__VA_ARGS__), __VA_ARGS__)
char** _s_list(size_t count, ...) {
int i;
va_list args;
va_start(args, count);
char **list = (char**)malloc(sizeof(char*) * count + 1);
assert(list != NULL);
for (i=0; i<count; i++) {
char *word = va_arg(args, char*);
list[i] = (char*)malloc(sizeof(char) * strlen(word) + 1);
assert(list[i] != NULL);
strcpy(list[i], word);
}
list[i] = (char*)malloc(sizeof(char) + 1);
assert(list[i] != NULL);
memset(list[i], 0, 1);
return list;
}
#define s_free(...) _s_free(__VA_ARGS__, 0)
void _s_free(char **list, size_t count, ...) {
int i;
for (i=0; (strcmp(list[i], "") != 0) || i < count; i++) {
free(list[i]);
}
free(list[i]);
free(list);
}
/*///////////////////////////////////
Testing:
///////////////////////////////////*/
int main() {
char **my_list = s_list("Hello world!", "foo", "bar", "foobar");
printf("%s\n", my_list[0]);
printf("%s\n", my_list[1]);
printf("%s\n", my_list[2]);
printf("%s\n", my_list[3]);
s_free(my_list); //if second argument is not specified, it will free until finds an empty string
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment