| STRNCPY(3) | Library Functions Manual | STRNCPY(3) |
stpncpy, strncpy
— copy fixed-width buffers with NUL
padding
Standard C Library (libc, -lc)
#include
<string.h>
char *
stpncpy(char
* restrict dst, const
char * restrict src,
size_t len);
char *
strncpy(char
* restrict dst, const
char * restrict src,
size_t len);
The
stpncpy()
and
strncpy()
functions fill a len-byte buffer at
dst by copying up to len
non-NUL bytes from src
followed by enough NUL bytes — possibly zero of them — to pad
the remainder.
The buffers src and dst may not overlap.
The buffer src is not required to hold a NUL-terminated string on input; it is only required either to have at least len bytes allocated and initialized, or to have a NUL byte if it is shorter than len bytes.
The buffer dst is not
guaranteed to hold a NUL-terminated string on output;
stpncpy()
and
strncpy()
write exactly len bytes to it, which includes nonempty
NUL padding only if a NUL byte appears in the first
len bytes at src.
The strncpy() function returns
dst.
The stpncpy() function returns a pointer
to the byte after the last non-NUL byte of
dst. This does not necessarily point to a NUL byte;
stpncpy() may return
&dst[len],
if all len bytes starting at src
are non- NUL.
The following logic fills a fixed-width field in a record that
might appear on disk with the content of a caller-provided string
str, padded to the end of the field with NUL
bytes:
struct record {
uint16_t id;
char name[6];
uint8_t tag;
...
};
struct record *rec = ...;
strncpy(rec->name, str, sizeof(rec->name));
The following values for str result in the
following corresponding contents of
rec->name:
str |
rec->name |
"abc\0" |
"abc\0\0\0" |
"abc\0\0\0" |
"abc\0\0\0" |
"abcde\0" |
"abcde\0" |
"abcdef\0" |
"abcdef" |
"abcdef" |
"abcdef" |
"abcdefghi\0" |
"abcdef" |
"abcdefghi" |
"abcdef" |
Note that when str has at
least six non-NUL bytes,
rec->name is
not NUL-terminated — it is only
padded with
(possibly zero) NUL bytes to fill the fixed-width buffer. When
str has
more than
six non-NUL bytes, the additional ones are
truncated. If str has space for
fewer
than six bytes, and the last one is not NUL, using
strncpy() is undefined.
Because strncpy() does
not guarantee to NUL-terminate the result, if
NUL-termination is required it must be done explicitly:
char buf[1024]; strncpy(buf, input, sizeof(buf) - 1); buf[sizeof(buf) - 1] = '\0';
If input is guaranteed to be NUL-terminated, and if buf need only be NUL-terminated, not fully initialized with NUL padding, this could be achieved using strlcpy(3) as follows:
strlcpy(buf, input, sizeof(buf));
It is not enough for input to have
sizeof(buf) bytes allocated; it MUST be
NUL-terminated for strlcpy(3)
to be used.
Note that because strlcpy(3) is not defined in any standards, it should only be used when portability is not a concern.
WARNING:
Because strlcpy(3) does not
fully initialize dst, but does read all the way to a
NUL terminator in src even past
len bytes,
strlcpy(3) is
not a safe NUL-terminating replacement for
strncpy(). Naively replacing
strncpy() by
strlcpy(3) can lead to
crashes, undefined behaviour, and disclosure of secrets from uninitialized
memory.
bcopy(3), memccpy(3), memcpy(3), memmove(3), strcpy(3), strlcpy(3), wcscpy(3)
The strncpy() function conforms to
ISO/IEC 9899:1999
(“ISO C99”).
The stpncpy() function conforms to
IEEE Std 1003.1-2008 (“POSIX.1”).
The stpncpy() function first appeared in
NetBSD 6.0.
The stpncpy() and
strncpy() functions are not guaranteed to
NUL-terminate the result.
| August 11, 2023 | NetBSD 11.0 |