strncat(3)
π strncat(3) β the "nonstring catenate" bestie π
okay so we're in the Library Functions Manual section, page 3, and today's main character is strncat β yes it's in the library, yes it's the C one, and bb it is not the function you think it is. buckle up π
β¨ NAME β¨
strncat β nonstring catenate π¦
π LIBRARY π
Standard C library (libc, -lc) π
πΈ SYNOPSIS πΈ
#include <string.h> // see memory.h(3head)
char *strncat(size_t ssize;
char *restrict dst, const char src[restrict ssize],
size_t ssize);
π DESCRIPTION π
so here's the vibe: strncat() appends at most ssize non-null bytes from the array that src points at, and then it slaps a null character on the end, appending all of that to the end of the string that dst points to. β¨
and dst must point to a string sitting inside a buffer that's big enough β like, the buffer size has to be at least strlen(dst) + strnlen(src, ssize) + 1. no notes, that's the requirement, fr fr. π
it's literally equivalent to this:
stpcpy(mempcpy(strnul(dst), src, strnlen(src, ssize)), ""), dst
π«Ά RETURN VALUE π«Ά
strncat() returns dst. that's it. that's the whole return value. iconic behavior honestly π
π ATTRIBUTES π
for the tea on all the terms used in this section, go peek at attributes(7).
- Interface:
strncat() - Attribute: Thread safety
- Value:
MT-Safe
(translation: she's safe to run from multiple threads, no cap π₯)
β STANDARDS β
C11, POSIX.1-2008.
π HISTORY π
POSIX.1-2001, C89, SVr4, 4.3BSD. she's been around, she's got lore π
π CAVEATS π
the name of this function is, and I say this with love, deeply confusing:
- it has no relation to
strncpy(3). zero. none. different girl entirely. - it does not truncate the input nonstring. nope.
β οΈ and listen β if the destination buffer doesn't already contain a string, or it isn't large enough, the behavior is undefined. undefined!! we do not do that here. see_FORTIFY_SOURCEinfeature_test_macros(7)for the safety rails. π¨
π EXAMPLES π
#include <stdcountof.h>
#include <stdio.h>
#include <string.h>
#include <utmp.h>
void print_ut_user(struct utmp *ut);
void
print_ut_user(struct utmp *ut)
{
char buf[countof(ut->ut_user) + 1];
strcpy(buf, "");
strncat(buf, ut->ut_user, countof(ut->ut_user));
puts(buf);
}
likeβ¦ look at her. countof for the buffer, empty string first, then catenate exactly as many bytes as fit, then puts. chef's kiss π§
π SEE ALSO π
memory.h(3head), string_copying(7)
and that's the whole page bestie π this was Linux man-pages 6.20, dated 2026-08-05, and honestly? slay. go forth and never overflow a buffer, ily, bye πβ¨π
π¦ where this page comes from
- arch rolling: man-pages 6.20-1 Β· BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
- nixpkgs unstable: man-pages 6.20
- π the page's license: Linux-man-pages-copyleft
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms