各位看官们,大家好,上一回中咱们说的是DIY字符串复制函数的例子,这一回咱们说的例子是:DIY字符串连接函数。闲话休提,言归正转。让我们一起talk C栗子吧!
我们在前面的章回中介绍过字符串连接函数,时间不长,但是有些看官已经忘记了,为了加深看官们对字符串复制函数的印象,我们准备DIY字符串连接函数。Just do it by yourself!
我们在前面的章回中一共介绍了两个字符串连接函数:strcat,strncat。接下来我们分别介绍如何DIY这两个字符串连接函数。
DIY strcat函数
char * diy_strcat(char *s1, const char *s2)
- 1.把指针移动到从s1小尾巴所在位置;
- 2.在s2所指的字符串中,从第一个字符开始,把s2中的字符,赋值给s1指向的字符;
- 3.判断是不是s2的小尾巴,如果是小尾巴,那么停止复制操作;如果不是,进入下一步;
- 4.重复步骤2和3,直到从步骤3中停止为止。
下面是我写的代码,大家可以参考,其实核心代码只有一行:
while((*pStr++ = *s2++) != '\0')
char * diy_strcat(char *s1, const char *s2)
{
char * pStr = NULL;
if(NULL == s2 || NULL == s2)
return NULL;
pStr = s1;
while(*pStr++ != '\0') // move the pointer to the end of s1
;
pStr--;
while((*pStr++ = *s2++) != '\0') // copy the char to s1
;
return s1;
}
从函数中可以看到,通过pStr–操作,可以覆盖掉s1中的小尾巴.在复制的过程中,程序会把s2指向字符串的小尾巴复制到s1中。
下面是标准库中strcat函数的实现,请大家和我们DIY的strcat函数进行对比:
/**
* strcat - Append one %NUL-terminated string to another
* @dest: The string to be appended to
* @src: The string to append to it
*/
char *strcat(char *dest, const char *src)
{
char *tmp = dest;
while (*dest)
dest++;
while ((*dest++ = *src++) != '\0')
;
return tmp;
}
通过对比,大家可以发现:两者的核心代码是相同的,不过标准库中的函数在处理s1末尾的小尾巴时,先判断再递增,而我们是一边判断一边递增。可见标准库使用的方法比咱们的简洁一些。
DIY strncat函数
char * diy_strncat(char *s1, const char *s2, int n)
- 1.把指针移动到从s1小尾巴所在位置;
- 2.在s2所指的字符串中,从第一个字符开始,把s2中的字符,赋值给s1指向的字符;
- 3.判断下面两个条件,只要满足了其中的任何一个条件 ,那么停止复制操作;如果两个条件都不满足,那么进入下一步:
- 条件一:赋值的字符是不是s2的小尾巴;
- 条件二:赋值的次数是不是超过了n次;
- 4.重复步骤2和3,直到从步骤3中停止为止;
- 5.通过判断复制的次数,在s1指向的字符串末尾添加小尾巴。
下面是我们DIY的strcat函数,大家可以参考:
char * diy_strncat(char *s1, const char *s2, int n)
{
char * pStr = NULL;
if(NULL == s2 || NULL == s2)
return NULL;
pStr = s1;
while(*pStr++ != '\0') // move the pointer to the end of s1
;
pStr--;
while( (*pStr++ = *s2++) != '\0' && (--n > 0)) // copy the char to s1
;
if(n == 0) // add \0 into the end of s1
*pStr = '\0';
return s1;
}
与strcat相比,我们在连接的过程中增加了对n的判断。可以说strncat是完全按照n进行连接操作的,这点与我们前面章回中说过的strncpy相同。不过strnat会在连接后的新串末尾添加小尾巴,而strncpy则不会添加,这点也strncpy完全不同。
下面是标准库中strncat函数的实现,请大家和我们DIY的strncat函数进行对比:
/**
* strncat - Append a length-limited, C-string to another
* @dest: The string to be appended to
* @src: The string to append to it
* @count: The maximum numbers of bytes to copy
*
* Note that in contrast to strncpy(), strncat() ensures the result is
* terminated.
*/
char *strncat(char *dest, const char *src, size_t count)
{
char *tmp = dest;
if (count) {
while (*dest)
dest++;
while ((*dest++ = *src++) != 0) {
if (--count == 0) {
*dest = '\0';
break;
}
}
}
return tmp;
}
通过对比,大家可以发现:标准库的函数比咱们DIY的要好一些,它先判断了n的值,然后才进行连接操作,
如果n的值为0就直接返回。不过,在连接过程的处理上,两者几乎是相同的。
看官们,我把这两个DIY函数整理成了一个文件,并且添加了详细的注释,除此之外,我还使用了前面章回中的测试case进行测试。正文中就不写代码了,详细的代码放到了我的资源中,大家可以点击这里下载使用。前面章回中的程序可以点击这里下载。
下面是程序运行的结果,请大家和前面章回中的程序运行结果进行对比。
addr: 0xbfc53d19 | s0 : string
addr: 0xbfc53d21 | s1 : str-1
addr: 0xbfc53d31 | s2 : str-2and123
addr: 0xbfc53d29 | s3 : AB
addr: 0xbfc53d17 | s4 : ABstring
----- after running diy_strcat(s1,s3) -----
addr: 0xbfc53d19 | s0 : string
addr: 0xbfc53d21 | s1 : str-1AB
addr: 0xbfc53d31 | s2 : str-2and123
addr: 0xbfc53d29 | s3 : AB
addr: 0xbfc53d17 | s4 : ABstring
----- after running diy_strcat(s1,s2) -----
addr: 0xbfc53d19 | s0 : string
addr: 0xbfc53d21 | s1 : str-1str-2and123
addr: 0xbfc53d31 | s2 :
addr: 0xbfc53d29 | s3 : -2and123
addr: 0xbfc53d17 | s4 : ABstring
----- after running diy_strncat(s3,cat,sizeof(char)*5) -----
addr: 0xbfc53d19 | s0 : string
addr: 0xbfc53d21 | s1 : str-1
addr: 0xbfc53d31 | s2 : str-2and123
addr: 0xbfc53d29 | s3 : ABcat
addr: 0xbfc53d17 | s4 : ABstring
----- after running diy_strncat(s1,s2,sizeof(char)*1) -----
addr: 0xbfc53d19 | s0 : string
addr: 0xbfc53d21 | s1 : str-1s
addr: 0xbfc53d31 | s2 : str-2and123
addr: 0xbfc53d29 | s3 : AB
addr: 0xbfc53d17 | s4 : ABstring
----- after running diy_strncat(s1,s2,sizeof(char)*2) -----
addr: 0xbfc53d19 | s0 : string
addr: 0xbfc53d21 | s1 : str-1st
addr: 0xbfc53d31 | s2 : str-2and123
addr: 0xbfc53d29 | s3 : AB
addr: 0xbfc53d17 | s4 : ABstring
----- after running diy_strncat(s1,s2,sizeof(char)*5) -----
addr: 0xbfc53d19 | s0 : string
addr: 0xbfc53d21 | s1 : str-1str-2
addr: 0xbfc53d31 | s2 : str-2and123
addr: 0xbfc53d29 | s3 : -2
addr: 0xbfc53d17 | s4 : ABstring
各位看官,关于DIY字符串连接函数的例子咱们就说到这里。欲知后面还有什么例子,且听下回分解。