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_SOURCE in feature_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