strncpy和strcpy区别_C语言strncpy
Defined in header <string.h> | ||
---|---|---|
(1) | ||
char *strncpy( char *dest, const char *src, size_t count ); | (until C99) | |
char *strncpy( char *restrict dest, const char *restrict src, size_t count ); | (since C99) | |
errno_t strncpy_s(char *restrict dest, rsize_t destsz, const char *restrict src, rsize_t count); | (2) | (since C11) |
1) Copies at most count
characters of the character array pointed to by src
(including the terminating null character, but not any of the characters that follow the null character) to character array pointed to by dest
.
If count
is reached before the entire array src
was copied, the resulting character array is not null-terminated.
If, after copying the terminating null character from src
, count
is not reached, additional null characters are written to dest
until the total of count
characters have been written.
The behavior is undefined if the character arrays overlap, if either dest
or src
is not a pointer to a character array (including if dest
or src
is a null pointer), if the size of the array pointed to by dest
is less than count
, or if the size of the array pointed to by src
is less than count
and it does not contain a null character.
2) Same as (1), except that the function does not continue writing zeroes into the destination array to pad up to count
, it stops after writing the terminating null character (if there was no null in the source, it writes one at dest[count] and then stops). Also, the following errors are detected at runtime and call the currently installed constraint handler function:
src
ordest
is a null pointerdestsz
orcount
is zero or greater than RSIZE_MAXcount
is greater or equaldestsz
, butdestsz
is less or equal strnlen_s(src, count), in other words, truncation would occur- overlap would occur between the source and the destination strings
The behavior is undefined if the size of the character array pointed to by dest
< strnlen_s(src, destsz) <= destsz
; in other words, an erroneous value of destsz
does not expose the impending buffer overflow. The behavior is undefined if the size of the character array pointed to by src
< strnlen_s(src, count) < destsz
; in other words, an erroneous value of count
does not expose the impending buffer overflow.
As with all bounds-checked functions,
strncpy_s
is only guaranteed to be available if
__STDC_LIB_EXT1__ is defined by the implementation and if the user defines __STDC_WANT_LIB_EXT1__ to the integer constant 1 before including string.h
.
Parameters
dest | – | pointer to the character array to copy to |
---|---|---|
src | – | pointer to the character array to copy from |
count | – | maximum number of characters to copy |
destsz | – | the size of the destination buffer |
Return value
1) returns a copy of dest
2) returns zero on success, returns non-zero on error. Also, on error, writes zero to dest[0] (unless dest
is a null pointer or destsz
is zero or greater than RSIZE_MAX) and may clobber the rest of the destination array with unspecified values.
Notes
As corrected by the post-C11 DR 468, strncpy_s
, unlike strcpy_s, is only allowed to clobber the remainder of the destination array if an error occurs.
Unlike strncpy
, strncpy_s
does not pad the destination array with zeroes, This is a common source of errors when converting existing code to the bounds-checked version.
Although truncation to fit the destination buffer is a security risk and therefore a runtime constraints violation for strncpy_s
, it is possible to get the truncating behavior by specifying count
equal to the size of the destination array minus one: it will copy the first count
bytes and append the null terminator as always: strncpy_s(dst, sizeof dst, src, (sizeof dst)–1);
Example
Run this code
#define __STDC_WANT_LIB_EXT1__ 1 #include <string.h> #include <stdio.h> #include <stdlib.h> int main(void) { char src[] = "hi"; char dest[6] = "abcdef"; // no null terminator strncpy(dest, src, 5); // writes five characters 'h', 'i', '\0', '\0', '\0' to dest printf("strncpy(dest, src, 5) to a 6-byte dest gives : "); for(size_t n = 0; n < sizeof dest; ++n) { char c = dest[n]; c ? printf("'%c' ", c) : printf("'\\0' "); } printf("\nstrncpy(dest2, src, 2) to a 2-byte dst gives : "); char dest2[2]; strncpy(dest2, src, 2); // truncation: writes two characters 'h', 'i', to dest2 for(size_t n = 0; n < sizeof dest2; ++n) { char c = dest2[n]; c ? printf("'%c' ", c) : printf("'\\0' "); } printf("\n"); #ifdef __STDC_LIB_EXT1__ set_constraint_handler_s(ignore_handler_s); char dst1[6], src1[100] = "hello"; int r1 = strncpy_s(dst1, 6, src1, 100); // writes 0 to r1, 6 characters to dst1 printf("dst1 = \"%s\", r1 = %d\n", dst1,r1); // 'h','e','l','l','o','\0' to dst1 char dst2[5], src2[7] = {'g','o','o','d','b','y','e'}; int r2 = strncpy_s(dst2, 5, src2, 7); // copy overflows the destination array printf("dst2 = \"%s\", r2 = %d\n", dst2,r2); // writes nonzero to r2,'\0' to dst2[0] char dst3[5]; int r3 = strncpy_s(dst3, 5, src2, 4); // writes 0 to r3, 5 characters to dst3 printf("dst3 = \"%s\", r3 = %d\n", dst3,r3); // 'g', 'o', 'o', 'd', '\0' to dst3 #endif }
Possible output:
strncpy(dest, src, 5) to a 6-byte dst gives : 'h' 'i' '\0' '\0' '\0' 'f' strncpy(dest2, src, 2) to a 2-byte dst gives : 'h' 'i' dst1 = "hello", r1 = 0 dst2 = "", r2 = 22 dst3 = "good", r3 = 0
References
- C11 standard (ISO/IEC 9899:2011):
- 7.24.2.4 The strncpy function (p: 363-364)
- K.3.7.1.4 The strncpy_s function (p: 616-617)
- C99 standard (ISO/IEC 9899:1999):
- 7.21.2.4 The strncpy function (p: 326-327)
- C89/C90 standard (ISO/IEC 9899:1990):
- 4.11.2.4 The strncpy function
From: https://en.cppreference.com/w/c/string/byte/strncpy
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/168104.html原文链接:https://javaforall.cn
相关文章
- java语言和C语言的区别
- 【安全算法之SHA256】SHA256摘要运算的C语言源码实现
- [linux] C语言Linux系统编程进程基本概念详解编程语言
- C语言空(null)指针和NULL指针的区别详解
- =与==的区别,C语言=与==的区别详解
- 数组指针和指针数组的区别,C语言数组指针和指针数组区别详解
- strlen函数与sizeof的区别,C语言strlen与sizeof的区别详解
- gets和fgets函数及其区别,C语言gets和fgets函数详解
- puts和fputs函数及其区别,C语言puts和fputs函数详解
- Linux与C语言:一个强大的组合(linux与c语言)
- 简易步骤:利用C语言创建MySQL数据库(c创建mysql数据库)
- 语言Linux下开发:从C语言到Python(linux下用什么编程)
- 版Linux下C语言编译器探索(c语言编译器linux)
- Linux串口编程:C语言实现(clinux串口编程)
- 使用Linux下C语言进行网络编程技巧(linux下c网络编程)
- 深入了解:使用Linux编译C语言程序(linux下编译c语言)
- Linux C语言程序调试:必要而有效.(linux c 代码调试)
- C语言编写的Redis类库,尽在你手中(c redis 类库)
- MySQL连接代码C语言实现(c mysql连接代码)
- 掌握利器从入门到精通的C语言与MySQL(c mysql怎么使用)
- 优雅的C语言编写Oracle语句块(c oracle 语句块)
- 实现Redis 为何选择使用C语言(为什么redis用c语言)