Skip to content

Instantly share code, notes, and snippets.

@lichrot
Last active August 10, 2022 14:33
Show Gist options
  • Save lichrot/e6be3feafb2e98891e87169a8be1d59b to your computer and use it in GitHub Desktop.
Save lichrot/e6be3feafb2e98891e87169a8be1d59b to your computer and use it in GitHub Desktop.
Variadic string concatenation in C with allocation (you most likely don't wanna use it)
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
int get_string_length(char* string) {
int size = 0;
while (*string != '\0') {
size += 1;
string += 1;
}
return size;
}
void copy_string(char* target, char* source) {
while (*source != '\0') {
*target = *source;
target++;
source++;
}
}
char* alloc_concat_strings(int arg_count, ...) {
va_list args;
va_start(args, arg_count);
int total_length = 0;
int* string_lengths = (int*)malloc(arg_count * sizeof(int));
if (string_lengths == NULL) return NULL;
char** string_pointers = (char**)malloc(arg_count * sizeof(char*));
if (string_pointers == NULL) return NULL;
for (int idx = 0; idx < arg_count; idx++) {
string_pointers[idx] = va_arg(args, char*);
string_lengths[idx] = get_string_length(string_pointers[idx]);
total_length += string_lengths[idx];
}
char* new_string = (char*)malloc(total_length * sizeof(char));
if (new_string == NULL) return NULL;
char* result = new_string;
for (int idx = 0; idx < arg_count; idx++) {
new_string += idx == 0 ? 0 : string_lengths[idx - 1];
copy_string(new_string, string_pointers[idx]);
}
free(string_lengths);
free(string_pointers);
return result;
}
int main() {
char* hello = "He11o";
char* world = "W0rl9";
char* separator = " ";
char* hello_world = alloc_concat_strings(3, hello, separator, world);
if (hello_world == NULL) return 1;
printf("%s", hello_world);
return 0;
}
@lichrot
Copy link
Author

lichrot commented Aug 10, 2022

Compiled assembly on Godbolt (best site evuh)

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