Programming Tips - C/C++: The best and safest way to copy strings in C/C++

Date: 2004oct22 Update: 2026apr27 Language: C/C++ Q. C/C++: The best and safest way to copy strings in C/C++ A. BAD REASON strcpy() no bounds checking lstrcpy() ditto - Windows only lstrcpyW() ditto - Windows only (Unicode) strncpy() terminating NUL isn't guaranteed GOOD REASON strcpyn() bounds checking and terminating NUL guaranteed strlcpy() ditto - BSD and gcc (Linux) strscpy() ditto - Linux kernel lstrcpyn() ditto - Windows only lstrcpynW() ditto - Windows only (Unicode) The Linux manual page for strcpy() says: If the destination string of a strcpy() is not large enough (that is, if the programmer was stupid/lazy, and failed to check the size before copying) then anything might happen. Overflowing fixed length strings is a favourite cracker technique. Q. What about string concatenation? A. BAD REASON strcat() no bounds checking lstrcat() ditto - Windows only lstrcatW() ditto - Windows only GOOD REASON strlcat() bounds checking and terminating NUL guaranteed - BSD, gcc strcat_s() ditto - Windows only Or use std::string or CString --------------------- Here is a full string copy example that works on Windows and Linux
#include <stdio.h> #include <string.h> // Has strlcpy() on Linux #ifdef _WIN32 #include "windows.h" // For lstrcpyn() on Windows #endif void portable_strlcpy(char *dest, const char *src, const size_t maxChars) { #ifdef _MSC_VER lstrcpyn(dest, src, maxChars); // Windows #else strlcpy(dest, src, maxChars); // Linux #endif } int main() { // Example use char buf[100] = "Something"; portable_strlcpy(buf, "Hello", sizeof(buf)); printf("buf=%s\n", buf); }
Outputs:
buf=Hello
--------------------- Here is a full string concatenate example that works on Windows and Linux
#include <stdio.h> #include <string.h> // Has strlcat() on gcc, has strcat_s() on Windows void portable_strlcat(char *dest, const char *src, const size_t size) { #ifdef _WIN32 strcat_s(dest, size, src); // Windows #else strlcat(dest, src, size); // Linux #endif } int main() { char buf[200] = ""; portable_strlcat(buf, "one ", sizeof(buf)); portable_strlcat(buf, "two ", sizeof(buf)); portable_strlcat(buf, "three ", sizeof(buf)); printf("buf=%s<\n", buf); }
Outputs:
buf=one two three <