深入理解strcpy,strncpy

转自出处


~对初学者属于深入理解吧,高手请勿在此浪费宝贵时间~


看到这样一个改错题:
char  p[ 5 ]; 
char *  s = " 12345 "
strcpy(p,s);
   cout << p << endl;
错误之处是很显然的,作为字符串字面值的"12345"会在结尾处自动加上空字符null,从而长度是6,上面的strcpy是会越界的,从而是个越界错误。
问题是我以为这样的程序编译的时候会出错呢!但是我在vc上运行时是可以输出正确结果的,这让我很是纳闷!后来找到了strcpy的源代码才知原因,strcpy函数是不进行越界处理的. 又因为strcpy连null一起复制,从而p能输出正确的结果"12345"
/*The strcpy function copies strSource, including the terminating null character, to the location specified by strDestination. No overflow checking is performed when strings are copied or appended. The behavior of strcpy is undefined if the source and destination strings overlap.*/
char   *  __cdecl strcpy( char   *  dst,  const   char   *  src) 

char * cp = dst; 

while*cp++ = *src++ ) 
/* Copy src over dst */ 

return( dst ); 
}
 
貌似strcpy虽然不进行越界处理,仍然是个挺好的函数呢,但是注意了,下面的代码就能暴露出strcpy 的缺点了.
char  p[ 5 ];
char   * =   " 12345678 " ;
strcpy(p,s);
cout 
<<  p  << endl;  // 输出12345678,而不是我们所设想的12345
为了不因不知s的长度而犯下错误,推荐使用strncpy。但是是不是用了strncpy就万无一失了呢?看下面的代码:
char  p[ 5 ];
char *  s  =   " 12345 " ;
strncpy(p,s,
5 );
cout 
<<  p  << endl;  // 12345*&^(后面表示乱码)
不是都限制个数了么?为什么后面又有乱码?
问题来自在上述情形strncpy是不会复制字符串s后面的null的,不是以null结束的p不会输出正确结果的。
仍然给出strncpy的源代码:
/*The strncpy function copies the initial count characters of strSource to strDest and returns strDest. If count is less than or equal to the length of strSource, a null character is not appended automatically to the copied string. If count is greater than the length of strSource, the destination string is padded with null characters up to length count. The behavior of strncpy is undefined if the source and destination strings overlap.*/
char   *  __cdecl strncpy (  char   *  dest,  const   char   *  source, size_t count ) 

char *start = dest; 

while (count && (*dest++ = *source++)) /* copy string */ 
count
--

if (count) /* pad out with zeroes */ 
while (--count) 
*dest++ = '\0'

return(start); 
}
 
那strncpy这么不稳定,为何用它?strncpy经常用于修改一个长字符串中间的一部分(看出不复制null的原因了吧!),如果实在要用到上述的代码上,就在代码最后加上p[5] = '\0'; 吧!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值