strncpy() does not guarantee that the copied string would be terminated with a null byte ('\0'). For a call that looks like strncpy(dst, src, n), if there is no null byte in the first n bytes of src, the string copied to dst would also not contain a null byte.
Here is an example code to demonstrate the problem:
#include <stdio.h>
#include <string.h>
int main()
{
char a[] = "01234567";
strncpy(a, "foobar", 4);
printf("%.8s\n", a);
return 0;
}
Here is the output: $ cc -std=c89 -Wall -Wextra -pedantic foo.c && ./a.out
foob4567
A C89-conforming alternative I use is a macro like this that guarantees '\0'-termination as the first thing: #define strcp(a, b, c) (a[0] = '\0', strncat(a, b, c - 1))
An example from my code: https://github.com/susam/uncap/blob/master/uncap.c#L78-L87Here is how to use it:
#include <stdio.h>
#include <string.h>
#define strcp(a, b, c) (a[0] = '\0', strncat(a, b, c - 1))
int main()
{
char a[] = "01234567";
strcp(a, "foobar", 4);
printf("%.8s\n", a);
return 0;
}
Here is the output: $ cc -std=c89 -Wall -Wextra -pedantic foo.c && ./a.out
foo