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 srccount 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 or dest is a null pointer
  • destsz or count is zero or greater than RSIZE_MAX
  • count is greater or equal destsz, but destsz 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 strncpystrncpy_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

strncpy, strncpy_s的更多相关文章

  1. c/c++头文件_string

    string, cstring, string.h 一.string头文件 主要包含一些字符串转换的函数 // sto* NARROW CONVERSIONS// sto* WIDE CONVERSI ...

  2. 字符串操作函数<string.h>相关函数strcpy,strcat,等源码。

    首先说一下源码到底在哪里找. 我们在文件中包含<cstring>时,如果点击右键打开文档, 会打开cstring,我们会发现路径为: D:\Program Files\visual stu ...

  3. strcpy、strncpy 和安全的strncpy_s

    strcpy和strncpy摘于linux 内核源码的/lib/string.c char *self_strcpy(char *dest, const char *src) { char *tmp ...

  4. C语言strcpy,strncpy和strlcpy讲解

    前言 C风格的字符串处理函数有很多,如strcpy().strcat()等等. strcpy与strcat char* strcpy (char* dest, const char* src); ch ...

  5. strcpy/strncpy/strcpy_s比较

    转载自:http://blog.csdn.net/caomiao2006/article/details/4766416 strcpy()是依据源串的/0作为结束判断的,不检查copy先的Buffer ...

  6. strncpy函数使用

    strncpy()函数原型:extern char *strncpy(char *dest, char *src, int n);    用法:#include <string.h>    ...

  7. Linux C 字符串函数 strlen()、strcat()、strncat()、strcmp()、strncmp()、strcpy()、strncpy() 详解

      strlen(返回字符串长度) 表头文件 #include <string.h> 定义函数 size_t strlen(const char *s); 函数说明 strlen()用来计 ...

  8. strncpy,strcpy

    strncpy不会为des自动添加“\0” strcpy遇空结束,自动添加结束符 结论: 1.使用strcpy时一定不能用于无结束符的字符串,因为strcpy依赖\0判断源字符串的结束 2.使用str ...

  9. [skill] strncpy里边有两个坑

    以前的笔记,今日翻出了复看了一下,转过来. ------------------------------------ 今天发现xxxdump中使用xxx_strncpy 替换 strncpy导致的bu ...

随机推荐

  1. css3实现旋转表

    如图所示: css部分: <style> #clock{width:100px; height:100px; border-radius:50%; border:4px solid bla ...

  2. 函数对象的call()、apply() 方法区别

    函数对象的call().apply() 方法 函数作为对象提供了call(),apply() 方法,他们也可以用来调用函数,这两个方法都接受一个对象作为参数,用来指定本次调用时函数中this的指向: ...

  3. js中的new Option默认选中

    new Option("文本","值",true,true).后面两个true分别表示默认被选中和有效! //js默认选中 var sel = document ...

  4. 框架MyBatis

    ByBatis MyBatis是Apache的一个开源项目iBatis,iBatis3.x 正式更名为MyBatis ,代码于2013年11月迁移到Github.它是一个基于Java的持久层框架(连数 ...

  5. redics在windows平台下的使用

    https://www.cnblogs.com/ding2011/p/4745732.html 一::下载    windows 下的redis: https://github.com/Service ...

  6. react 性能优化

    React 最基本的优化方式是使用PureRenderMixin,安装工具 npm i react-addons-pure-render-mixin --save,然后在组件中引用并使用 import ...

  7. CLR Via 第一 章 知识点整理(1)

    写这个纯粹是自己的一点学习总结,其实就学习的笔记整理,相当于对自己的一点督促,如有看到不正确的欢迎指出 一般我们写代码都是使用的高级语言,但是在CLR中运行的代码并不是我们直接写的代码,而是通过我们选 ...

  8. Effective前端2---加快页面打开速度

    1.避免head标签JS阻塞 所有放在head标签里的JS和CSS都会阻塞页面渲染.如果这些CSS和JS需要记在时间比较久,中间页面会存在一个空白期,严重影响到用户体验. 例如以下代码:在head标签 ...

  9. Zend 无限试用

    1.显示你的隐藏文件.文件夹 2.删除以下文件.文件夹 文件夹:C:\Users\Administrator\.zend\ 文件夹:C:\Users\Administrator\.ZendStudio ...

  10. 如何去掉linux配置文件的注释行和空行

    1.使用grep -v "^#"  来去掉注释行,其中:-v  就是取相反的   ^# 表示以#开头的行 eg. grep -v "^#" /etc/vsftp ...