3 ms·
// This code is licensed under CC0. // A copy of the license can be obtained at https://creativecommons.org/publicdomain/zero/1.0/ // May you forever catena
by efaref 11y ago
// This code is licensed under CC0.
// A copy of the license can be obtained at https://creativecommons.org/publicdomain/zero/1.0/
// May you forever catenate in peace.
#define strncatm(dest, sz, ...) strncat_multi((dest), (sz), __VA_ARGS__, NULL);
char* strncat_multi(char *dest, size_t dest_sz, ...) {
va_list srcs;
char *dest_end;
const char *src;
size_t src_sz;
size_t dest_off;
size_t copy_sz;
va_start(srcs, dest_sz);
for (dest_end = dest, dest_off = 0; *dest_end && dest_off < dest_sz; dest_end++, dest_sz++);
for (src = va_arg(srcs, const char *); src && dest_off < dest_sz; src = va_arg(srcs, const char *)) {
src_sz = strlen(src);
copy_sz = src_sz < (dest_sz - dest_off) ? src_sz : (dest_sz - dest_off);
memmove(dest_end, src, copy_sz);
dest_end += copy_sz;
dest_off += copy_sz;
if (dest_off < dest_sz)
{
*dest_end = '\0';
}
}
va_end(srcs);
return dest_end;
}
- anon4 11y agoGood, but I'd do one modification -- always write a null byte at the end. Otherwise you end up with a non-null-terminated string and that's bad. So, copy_sz = src_sz < (dest_sz - dest_off) ? src_sz : (dest_sz - dest_off - 1); ... *dest_end = '\0';