Usage of strncpy: The difference between strcpy and strcpy lies in copying n characters instead of copying all characters (including '\ 0' at the end ').
Function prototype: char * strncpy (char * dst, const char * src, int n)
When the src length is less than n, the uncopied space in dst is filled with '\ 0. Otherwise, n characters are copied to dst without '\ 0 '. Note that '\ 0' is added to the end of the string dst.
Many people know how to use strncpy, strncpy, and strlcpy to replace strcpy to prevent Buffer Overflow. However, if you still need to consider the running efficiency, strlcpy may be a better way.
1. strcpy
We know that strcpy is judged based on \ 0 and will automatically add \ 0 after the string in the buffer. If the to space is insufficient, it will cause buffer overflow. The general implementation code of strcpy is as follows (from OpenBSD 3.9 ):
Char * strcpy (char * to, const char * from)
{
Char * save =;
For (; (* to = * from )! = '\ 0'; ++ from, ++ );
Return (save );
}
But generally, our from is derived from user input, which is probably a very large string, so strcpy is not safe enough.
2. strpolic_s
It should have the same functions as the strcpy () function. The strcpy function, just like the gets function, has no way to ensure a valid buffer size, so it can only assume that the buffer is large enough to accommodate the string to be copied. When the program runs, this will lead to unpredictable behavior. Use strcpy_s to avoid these unexpected behaviors.
This function can be used with two or three parameters, as long as the buffer size can be guaranteed.
When there are three parameters:
Errno_t strcpy_s (
Char * strDestination,
Size_t numberOfElements,
Const char * strSource
);
When there are two parameters:
Errno_t strcpy_s (
Char (& strDestination) [size],
Const char * strSource
); // C ++ only
Note that if two parameter versions are required, the space pointed to by strDestination must be statically allocated instead of the heap memory dynamically new.
3. strncpy
In ansi c, the secure version of strcpy is strncpy.
Char * strncpy (char * s1, const char * s2, size_t n );
But strncpy's behavior is very strange (not in line with our usual habits ). The standard stipulates that n is not sizeof (s1), but the number of char to be copied. One of the most common problems is that strncpy does not help you ensure \ 0 is over.
Char buf [8];
Strncpy (buf, "abcdefgh", 8 );
Looking at this program, the buf will be filled with "abcdefgh", but there is no \ 0 Terminator.
In addition, if s2 has less content and n is large, strncpy will fill the space between them with \ 0. This introduces another efficiency problem, as shown below:
Char buf [80];
Strncpy (buf, "abcdefgh", 79 );
The strncpy above will fill in 79 char, not just "abcdefgh" itself.
The standard usage of strncpy is: (manually write \ 0)
Strncpy (path, src, sizeof (path)-1 );
Path [sizeof (path)-1] = '\ 0 ';
Len = strlen (path );
4. strlcpy
Copy src to a buffer with a size of siz, a maximum of siz-1 copies, the siz position is added '\ 0', returns strlen (src) after execution ends ). Therefore, if retval> = siz, src is truncated because the destination buffer is too small.
Size_t strlcpy (char * dst, const char * src, size_t siz );
To use strlcpy, we do not need to manually take charge of \ 0. We only need to inform strlcpy of sizeof (dst:
Strlcpy (path, src, sizeof (path ));
Len = strlen (path );
If (len> = sizeof (path ))
Printf ("src is truncated .");
In addition, strlcpy returns strlen (str), so we can easily determine whether the data is truncated, but also to the program buried a ray, so, strlcpy does not belong to ansi c and is not yet a standard.