`strcpy()` and `strncpy()` were defined at the same time, but to understand `strncpy()` you have to understand the original Unix file system. Directories are special files that map names to inodes [1]. Back then, each entry in a directory was 16 bytes---14 for the name, and 2 bytes for the inode number. `strncpy()` was designed to slap filenames into the directory; adding a NUL byte would either restrict filenames to 13 bytes, or overwrite the inode number. Also remember, this was done in the early 70s, when space was at a premium and computers weren't networked with every other computer in the world. It was a different time then.
The ANSI committee, when standardizing C, were trying to keep existing code valid when possible. Up until that time, you had a lot of different C libraries. Some defined `bzero()` to clear memory, others defined `memset()`. The C committee had to distill all these conflicting libraries so as to minimize the work each C vendor had to do to get a conforming C library.
[1] Inodes contain all information about a file except its name. Still true today.
The ANSI committee, when standardizing C, were trying to keep existing code valid when possible. Up until that time, you had a lot of different C libraries. Some defined `bzero()` to clear memory, others defined `memset()`. The C committee had to distill all these conflicting libraries so as to minimize the work each C vendor had to do to get a conforming C library.
[1] Inodes contain all information about a file except its name. Still true today.