strncpy介绍

 strncpy()函数
原型:extern char *strncpy(char *dest, char *src, int n);    
用法:#include <string.h>    
功能:把src所指由NULL结束的字符串的前n个字节复制到dest所指的数组中。    
说明:如果src的前n个字节不含NULL字符,则结果不会以NULL字符结束。        
如果src的长度小于n个字节,则以NULL填充dest直到复制完n个字节。        
src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。        
返回指向dest的指针(该指向dest的最后一个元素)    

当然喽,strncpy要保证src<dest串长度才是最重要的。这一点函数本身不保证,通过设置合理的n的值来保证安全性。

说strncpy其实还是会出现栈溢出,乱码等现象。如果我们不对n的值合理使用的话。

说明:

如果:n > dest串长度,dest栈空间溢出产生崩溃异常。

否则:

  1)src串长度<=dest串长度,(这里的串长度包含串尾NULL字符)

  如果n=(0, src串长度),src的前n个字符复制到dest中。但是由于没有NULL字符,所以直接访问dest串会发生栈溢出的异常情况。

  如果n = src串长度,与strcpy一致。

  如果n = dest串长度,[0,src串长度]处存放src字串,(src串长度, dest串长度]处存放NULL。

  2)src串长度>dest串长度

  如果n =dest串长度,则dest串没有NULL字符,会导致输出会有乱码。如果不考虑src串复制完整性,可以将dest最后一字符置为NULL。

  综上,一般情况下,使用strncpy时,建议将n置为dest串长度(除非你将多个src串都复制到dest数组,并且从dest尾部反向操作),复制完毕后,为保险起见,将dest串最后一字符置NULL,避免发生在第2)种情况下的输出乱码问题。当然喽,无论是strcpy还是strncpy,保证src串长度<dest串长度才是最重要的。

 

void main()
{
    char buf[8];
    strncpy(buf, "12345678", 9);
    //buf[7] = '\0';
    printf("%s\n", buf);
    system("pause");
}

可以编译通过,但是会出现栈溢出。

 

void main()
{
    char buf[8];
    strncpy(buf, "12345678", 8);
    //buf[7] = '\0';
    printf("%s\n", buf);
    system("pause");
}

乱码

 

 

2. strncpy

在 ANSI C 中,strcpy 的安全版本是 strncpy。

char *strncpy(char *s1, const char *s2, size_t n);

但 strncpy 其行为是很诡异的(不符合我们的通常习惯)。标准规定 n 并不是 sizeof(s1),而是要复制的 char 的个数。一个最常见的问题,就是 strncpy 并不帮你保证 \0

结束。

char buf[8];
strncpy( buf, "abcdefgh", 8 );

看这个程序,buf 将会被 "abcdefgh" 填满,但却没有 \0 结束符了。

另外,如果 s2 的内容比较少,而 n 又比较大的话,strncpy 将会把之间的空间都用 \0 填充。这又出现了一个效率上的问题,如下:

char buf[80];
strncpy( buf, "abcdefgh", 79 );

上面的 strncpy 会填写 79 个 char,而不仅仅是 "abcdefgh" 本身。


strncpy 的标准用法为:(手工写上 \0)

strncpy(path, src, sizeof(path) - 1);
path[sizeof(path) - 1] = '\0';
len = strlen(path);

posted @ 2017-04-19 16:21  ren_zhg1992  阅读(473)  评论(0)    收藏  举报