字符串处理函数(strcat、strcpy等)为什么要返回值

这样做的目的是方便程序中语句内联,比如strlen(strcpy(s,t))。

为了实现链式操作,将目的地址返回

int lengh=strlen(strcpy(s,t))。

Strcpy函数可以作为另外一个函数的实参。

char * strcpy( char *strDest, const char *strSrc ) 
{
 assert( (strDest != NULL) && (strSrc != NULL) );
 char *address = strDest; 
 while( (*strDest++ = * strSrc++) != '\0’ ); 
  return address;
}

字符串复制

最常见的字符串复制函数是strcpy:

char *strcpy(char *dst, const char *src);

把src所指的由NULL结尾的字符串复制到由dst所指的字符串中,src和dst不可以相同(可以由c99的restrict关键字声明),dst必有足够的空间存放复制的字符串。

还有一点要注意的是函数返回值,返回值是指向dst的指针,这样做的目的是方便程序中语句内联,比如strlen(strcpy(s,t))。

函数的实现如下:

  1. char *my_strcpy(char *dst, const char *src){  
  2.     assert(NULL!=dst && NULL!=src);  
  3.     char *p = dst;  
  4.     while((*dst++ = *src++) != '\0');  
  5.     return p;  
  6. }  
char *my_strcpy(char *dst, const char *src){
	assert(NULL!=dst && NULL!=src);
	char *p = dst;
	while((*dst++ = *src++) != '\0');
	return p;
}

使用strcpy是危险的,因为函数本身是不检查dst指向的空间是否足够存储需要复制的字符串,导致的一个潜在隐患就是字符串溢出。这也是上个世纪常被黑客利用的一个经典漏洞。所以,在大多数情况下都是用strncpy无疑更加保险:

  1. char *my_strncpy(char *dst, const char *src, size_t n){  
  2.     assert(NULL!=dst && NULL!=src);  
  3.     char *p = dst;  
  4.     while(n){  
  5.         if((*dst++ = *src++) == '\0')  
  6.             break;  
  7.         n--;  
  8.     }  
  9.     return p;  
  10. }  
char *my_strncpy(char *dst, const char *src, size_t n){
	assert(NULL!=dst && NULL!=src);
	char *p = dst;
	while(n){
		if((*dst++ = *src++) == '\0')
			break;
		n--;
	}
	return p;
}

需要注意另外一个函数strdup:

char *strdup(const char *);

该函数和strcpy的不同是,函数会自己申请内存空间存放拷贝的字符串,然后返回指向该字符串的指针。所以在使用strdup函数时需要注意的是,在使用完复制的字符串后使用free函数释放其占用的空间。

另memcpy函数和strncpy类似,只是不会再遇到NULL时终止拷贝,该函数一定会拷贝n个字符。

字符串连接

字符串连接是把一个字符串的头连接到另一个字符串的结尾。

char *strcat(char *s1, const char *s2);

函数的实现如下:

  1. char *my_strcat(char *s1, const char *s2){  
  2.     assert(NULL!=s1 && NULL!=s2);  
  3.     char *p =s1;  
  4.     while(*s1)s1++;  
  5.     strcpy(s1,s2);  
  6.     return p;  
  7. }  
char *my_strcat(char *s1, const char *s2){
	assert(NULL!=s1 && NULL!=s2);
	char *p =s1;
	while(*s1)s1++;
	strcpy(s1,s2);
	return p;
}

同样,strcat也是不安全的,因为也对缓冲区足够存放连接的字串进行了假设。所以,多数情况下我们应该使用更安全的:

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

  • 11
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我会根据您的要求回答您的问题。 (1)使用字符数组作为函数参数,求字符串长度的函数strLen: ```c++ int strLen(char s[]) { int len = 0; for (int i = 0; s[i] != '\0'; i++) { len++; } return len; } ``` 测试代码: ```c++ char s[] = "hello world"; printf("字符串长度为:%d\n", strLen(s)); ``` 输出结果:字符串长度为:11 (2)使用字符指针作为函数参数,字符串复制函数strCpy: ```c++ void strCpy(char* dest, const char* src) { while (*src != '\0') { *dest = *src; dest++; src++; } *dest = '\0'; } ``` 测试代码: ```c++ char s1[] = "hello"; char s2[10]; strCpy(s2, s1); printf("复制后的字符串为:%s\n", s2); ``` 输出结果:复制后的字符串为:hello (3)使用字符数组作为函数参数,字符串连接函数strCat: ```c++ void strCat(char s1[], const char s2[]) { int i, j; i = j = 0; while (s1[i] != '\0') { i++; } while (s2[j] != '\0') { s1[i] = s2[j]; i++; j++; } s1[i] = '\0'; } ``` 测试代码: ```c++ char s1[20] = "hello"; char s2[] = "world"; strCat(s1, s2); printf("连接后的字符串为:%s\n", s1); ``` 输出结果:连接后的字符串为:helloworld (4)使用字符指针作为函数参数,字符串比较大小函数strCmp: ```c++ int strCmp(const char* s1, const char* s2) { while (*s1 != '\0' && *s2 != '\0') { if (*s1 > *s2) { return 1; } else if (*s1 < *s2) { return -1; } s1++; s2++; } if (*s1 == '\0' && *s2 == '\0') { return 0; } else if (*s1 == '\0') { return -1; } else { return 1; } } ``` 测试代码: ```c++ char s1[] = "hello"; char s2[] = "hello world"; printf("比较结果为:%d\n", strCmp(s1, s2)); ``` 输出结果:比较结果为:-1

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值