c语言字符串函数之strcpy,strcat,strncpy,strncat函数解析

      char* strcpy(char *dst, char const * src)
      {
           assert((src != NULL) && (dst != NULL));
           char *tmp = dst;
           while ((*dst++ = *src++) != '\0');
           return tmp
      } 

      上述即为strcpy函数实现。如果参数src和dst在内存中出现重叠,其结果是未定义的。程序员必须保证dst足够长,否则的话,如果src长达大于dst,那么为了把src复制给dst,会侵占dst数组后面的部分内存空间,改写原先恰好存储在那里的变量。例如,看如下代码:

      chap dst[5];
      char *src = "abcde";   //会在末尾加上NULL字节,所以该字符串长度为6
      strcpy(dst, src);

     上面,dst长度为5,而src长度为6,肯定会侵占dst后面一个字节的内存,但在语法上是正确的,别想编译器给你报错。这肯定是一个隐藏的bug。

     char* strcat(char *dst, char const* src)
     {
           char *tmp = src;
           while (*dst)
              ++dst;
           while ((*dst++ = *src++) != '\0');         //该循环结束时,已将将src的NUL字节复制给了dst
           return tmp
     }

      上述即为strcat函数实现。同strcpy一样,程序员必须保证dst足够长,否则会侵占dst后面的部分内存空间。

      char* strncpy(char* dst, char const *src, size_t count)
      {
          char * tmp = dst;
          while (count && (*dst++ = *src++))      //判断src是否到达末尾,且待复制的字节数是否减为0
                 --count;
          if (count)                  //如果count!=0,即src到达末尾,则在末尾添加count个NUL字节,若coun==0,复制完成。返回
                while (--count)
                 *dst = '\0'
          return tmp
      }

       这个函数是不安全的。它调用的结果可能不是一个字符串,因为字符串必须以NUL字节结尾。如果在一个需要字符串的地方使用了一个不是以NUL字节结尾的字符序列,会发生什么呢?这个问题只有当你使用strncpy函数创建字符串,然后或者对它们使用str开头的库函数,或者在printf中使用%s格式码打印它们时才会发生。在使用不收限制的函数之前,你首先必须确保字符串实际上是以NUL字节结尾的,例如,考虑以下代码段:

        char buffer[BUFSIZE]
        .........
        strncpy(buffer, name, BUFSIZE)
        buffer[BUFSZE - 1] = '\0'
char* strncat(char *dst, const char* src, size_t count)
{
	if (count)
	{
		char *tmp = dst;
		const char *s = src;
		while (*tmp)					//循环结束时,tmp指向了NUL字节。
			tmp++;
		do 
		{
			if ((*tmp = *src++) == 0)	//这里src第一个字符覆盖了dst原本的NUL字节
				break;
			tmp++;
		} while (--count);
		*tmp = 0;                      //复制完毕后,将最后一个字节置为NUL字节
	}
	return dst;
}       
       

     与strncpy不同的时,在结束时,strncat总是在结果字符串的后面添加一个NUL字节,而且它不会像strncpy那样对目标数组用NUL字节进行填充。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值