Differences between string copy functions strcpy, strcat, sprintf, strncpy, strncat and snprintf

Source: Internet
Author: User
There should be a lot of discussions about strcpy, sprintf, and strcat insecure functions. We all know that they can be replaced by strncpy, snprintf, and strncat. However, in actual work, it seems that these "Security edition" functions still bring a lot of questions. I have summarized them and listed them here.

1. sprintf (char * STR, const char * format,...)-> snprintf (char *
STR, size_t size, const char * format ,...)

Vsprintf (char * STR, const char * format, va_list AP)->
Vsnprintf (char * STR, size_t size, const char * format, va_list AP)

According to the C/C ++ standard, snprintf and vsnprintf will never output more characters (including '\ 0' at the end) than the number of bytes specified by size to Str '), they also ensure that '\ 0' will be written into STR, so you don't have to worry about the end after using this function.

Example:
Char Buf [5];
Snprintf (BUF, 5, "this is a test string."); // Buf becomes "this ",
Buf [4] is '\ 0' snprintf (BUF, 6, "this is a test string."); // error:
Buffer overflow snprintf (BUF, 5, "ABC"); // Buf becomes "ABC",
Value of BUF [3] is '\ 0', Buf [4] is undefined.
However, the _ snprintf function in VC does not follow this rule. When the output buffer is not large enough, it will not output the ending '\ 0' (similar to strncpy ). To make the above program work normally, you must make corresponding modifications.
Char Buf [5]; _ snprintf (BUF, 5, "this is a test string."); // Buf becomes
"This", Buf [4] is ''Buf [4] = 0 ;//
Buf [4] is '\ 0' now. _ snprintf (BUF, 6, "this is a test string .");//
Error: Buffer Overflow _ snprintf (BUF, 5, "ABC"); // Buf becomes "ABC ",
The value of BUF [3] is '\ 0', Buf [4] is undefined.
To ensure portability, you have to follow the VC method and perform a lot of "fill 0" operations for the standard, define a macro to distinguish the platform from snprintf or _ snprintf.

2. strcat (char * DEST, const char * SRC)-> strncat (char * DEST,
Const char * SRC, size_t N );

This function is relatively simple. It ensures that no more than N + 1 characters are written and ends with '\ 0' at the end.

Example:
Char Dest [5] = "ABC ";
Strncat (DEST, "defghijklmn", 5-3-1); // DEST becomes "ABCD ",
Dest [4] is '\ 0', // always minus the buffer length by 1 as the value
N. strncat (DEST, "defghijklmn", 5-3); // error: Buffer Overflow

3. strcpy (char * DEST, const char * SRC)-> strncpy (char * DEST,
Const char * SRC, size_t N );

Strncpy is a relatively error-prone function. It ensures that no more than n Bytes of SRC are copied. However, if the first n Bytes of SRC do not contain '\ 0',
The Dest does not normally terminate with '\ 0. In addition, it ensures that if the SRC length is less than N, the rest of the Dest will be filled with '\ 0. When using this function, there is a best practice.
DeST is first filled with 0, and the value of DeST length minus 1 is passed as N, which ensures security.

Example:
Char Buf [5] = {0}; // always zero-fill the buffer,
// Always use this form to initialize the stack
Arrays to get // better performance over memset.
Char * buf2 = new char [5];
Memset (buf2, 0, 5); // always zero-fill the buffer
Strncpy (BUF, "ABCDE", 5); // error: Buf is not null-terminated.
Strncpy (buf2, "ABCDE", 5-1); // right, always minus the buffer
Length by 1 // as the value of N. Buf becomes "ABCD", Buf [4]
// Is '\ 0' by initilization;
// This is a common error in the existing code.
Char buf3 [5];
Const char * STR = "test ";
Strncpy (buf3, STR, strlen (STR); // wrong, Buf may not
Null-terminated, // potential buffer-overflow
Strncpy (buf3, STR, strlen (STR) + 1); // wrong, potential
Buffer-overflow. // no difference with using strcpy.

Function Description
Char * strncpy (char * DEST, const char * SRC, size_t N );
A maximum of n characters can be copied from SRC to DeST. If the size of SRC is less than N, the remaining part of DeST will be filled with 0;
If the size of SRC is greater than or equal to N, the rest of DeST will not be filled with 0, so DEST will not end with 0.

Char * strncat (char * DEST, const char * SRC, size_t N );
Copy up to n characters from the source to the target string, and add a 0 character to the end. That is to say, at most N + 1 characters can be written into DeST. If the Dest capacity is N, the Dest will overflow.

Int snprintf (char * STR, size_t size, const char * format ,...);
Copy a maximum of size-1 characters from the source string to the target string, and add 0 to the end. Therefore, if the size of the target string is size, it will not overflow.

Therefore, snprintf is recommended for string copying.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.