您的位置:首页 > 编程语言 > C语言/C++

一起talk C栗子吧(第六十一回:C语言实例--字符串连接)

2015-11-16 23:49 405 查看
各位看官们,大家好,上一回中咱们说的是字符串复制的例子,这一回咱们说的例子是:字符串连接。闲话休提,言归正转。让我们一起talk C栗子吧!

看官们,在C语言的标准库中为我们提供了字符串连接函数,我们只需要包含string.h头文件就可以使用字符串连接函数。这点和字符串复制函数一样,标准库提供了两个字符串连接函数:strcat和strncat。接下来我们分别介绍它们的用法和使用时的注意事项。

1. strcat函数

strcat函数原型:char * strcat(char *s1, const char *s2)

strcat函数用法:它把s1和s2中的内容连接在一起,并且返回s1.

strcat注意事项:连接的时候s1中的小尾巴会被覆盖掉,但是它会把s2中的小尾巴复制过来,并且当作新串的小尾巴。还一个需要注意的事项是,如果s2中的内容太多,以至于超过s1的容量,那么会覆盖掉s1后面内存中的内容。这点和stcpy是一样的。我们举一个实际的例子来说明,在程序中定义如下字符串:

char s0[SIZE] = "string";
char s1[SIZE]="str-1";
char s2[SIZE+3]="str-2and123";
char s3[SIZE] = {'A','B'};// other element of s3 is \0
char s4[] = {'A','B'};    // there is loss of \0 at the end of string


在执行strcat(s1,s3)前和strcat(s1,s2)后分别显示这些字符串的内存地址和字符串的内容,结果如下:

addr: 0xbfb33919 | s0 : string
addr: 0xbfb33921 | s1 : str-1
addr: 0xbfb33931 | s2 : str-2and123
addr: 0xbfb33929 | s3 : AB
addr: 0xbfb33919 | s4 : ABstring
----- after running strcat(s1,s3) -----
addr: 0xbfb33919 | s0 : string
addr: 0xbfb33921 | s1 : str-1AB  // it show a correct result
addr: 0xbfb33931 | s2 : str-2and123
addr: 0xbfb33929 | s3 : AB
addr: 0xbfb33919 | s4 : ABstring
----- after running strcat(s1,s2) -----
addr: 0xbfb33919 | s0 : string
addr: 0xbfb33921 | s1 : str-1str-2and123  // it show a correct result
addr: 0xbfb33931 | s2 :                   // it show a wrong result
addr: 0xbfb33929 | s3 : -2and123          // it show a wrong result
addr: 0xbfb33919 | s4 : ABstring


大家从程序的运行结果中可以看到,执行strcat(s1,s3)后,s1被连接后,新串的长度没有超过连接前的长度,程序显示正确的结果:连接操作把s1和s3中的内容连接在一起,同时覆盖掉了s1的小尾巴,而且还把s3的小尾巴当作了连接后新串的小尾巴。

执行strcat(s1,s2)后,s1被连接后,新串的长度已经超过连接前的长度,这会把覆盖掉其它内存中的内容。因此程序会显示错误的结果:连接操作把s1和s2中的内容连接在一起,但是也把相邻的内存空间污染了。

从上面的结果可以看到,因为s1的内存空间和s3的内存空间相邻,所以s3已经中了躺枪。而且新串的长度太长了,把内存空间中与s3相邻的s2也给污染了。真是“福无双至,祸不单行”呀,污染一个字符串的内存空间还不够,把两个字符串的内存空间都给污染了。

看官们,刚才的例子够触目惊心了吧,其实标准库已经知道strcat存在这样的缺陷,因此它还提供了另外一个字符串连接函数:strncat.接下来我们介绍一下strncat这个函数。

2.. strncat函数

strncat函数原型:char * strcat(char *s1, const char *s2,size_t n)

strncat函数用法:它把s2中的前n个字符和s1中的内容连接在一起,并且返回s1.

strncat注意事项:如果s2中的字符数量大于n,那么只连接n个字符到s1中,而且会在n个字符后面加上字符串的小尾巴。如果s2中的字符数量小于n,那么会连接s2中所有的字符,不足的用空字符:\0进行补充,直到n个字符为止。

我们一般的经验是,在连接时设置n的值比s1的剩余空间小于1,留下一个字符的内存空间,请该函数自动给s1加上小尾巴。如果n的值大于s1的容量就和strcat一样了。引入strncat就是为了通过n来控制连接的内容,避免类似strcat连接字符串时的缺陷。因此,我们要用好n这张牌。关键时候来个一招制胜,哈哈。这张牌好像在哪里见过?没错!在strncpy时我们见过这张牌。strncat连接字符串的操作和strncpy复制字符串的操作类似,不同之处在于strncat会自动在连接后的新字符串后面加上小尾巴,而strncpy则需要我们手动去添加小尾巴。

我们举一个实际的例子来说明,程序中还使用刚才定义的字符串,在执行strncat前和strncat后分别显示这些字符串的内存地址和字符串的内容,结果如下:

----- after running strncat(s3,cat,sizeof(char)*5) -----
addr: 0xbff4a419 | s0 : string
addr: 0xbff4a421 | s1 : str-1
addr: 0xbff4a431 | s2 : str-2and123
addr: 0xbff4a429 | s3 : ABcat //s3 and "cat" are catenated correctly
addr: 0xbff4a417 | s4 : ABstring
----- after running strncat(s1,s2,sizeof(char)*1) -----
addr: 0xbff4a419 | s0 : string
addr: 0xbff4a421 | s1 : str-1s //s1 and 1 char of s2 are catenated correctly
addr: 0xbff4a431 | s2 : str-2and123
addr: 0xbff4a429 | s3 : AB
addr: 0xbff4a417 | s4 : ABstring
----- after running strncat(s1,s2,sizeof(char)*2) -----
addr: 0xbff4a419 | s0 : string
addr: 0xbff4a421 | s1 : str-1st //s1 and 2 char of s2 are catenated correctly
addr: 0xbff4a431 | s2 : str-2and123
addr: 0xbff4a429 | s3 : AB
addr: 0xbff4a417 | s4 : ABstring
----- after running strncat(s1,s2,sizeof(char)*5) -----
addr: 0xbff4a419 | s0 : string
addr: 0xbff4a421 | s1 : str-1str-2 //s1 and 5 char of s2 are catenated
addr: 0xbff4a431 | s2 : str-2and123
addr: 0xbff4a429 | s3 : -2        // s3 is pollution
addr: 0xbff4a417 | s4 : ABstring


我们使用strncat(s1,s2,n)进行了四次连接操作:

第一次连接时,s2中字符的数量小于n,s1和s2的内容连接在了一起,而且给连接后的新串加上了小尾巴;

第二次连接时,s2中字符的数量大于n,s1和s2中前n个字符连接在了一起,而且在连接后的新串中自动加上了小尾巴;

第三次连接时,s2中字符的数量大于n,s1和s2中前2个字符连接在了一起,而且在连接后的新串中自动加上了小尾巴。

第四次连接时,n的值大于了s1的空间容量,s1和s2虽然连接在了一起,但是s1污染了其它的内存空间,这和strcat的做法一样,刚才已经分析过,这里就不再详细分析了。

这是我们推荐的做法:在连接字符串时n和值加上1小于或者等于s1中的字符数量。也就是第三次连接操作。

看官们,我把所有的例子整理成了一个文件,并且添加了详细的注释。正文中就不写代码了,以免显得乱,详细的代码放到了我的资源中,大家可以点击这里下载使用。

各位看官,关于字符串连接的例子咱们就说到这里。欲知后面还有什么例子,且听下回分解。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: