C语言string.h库strncpy与strncat异常行为问题求解
异常行为成因说明
1. name5 输出乱码的原因
C标准中strncpy的设计逻辑不会主动为目标缓冲区追加字符串结束符\0,规则如下:
- 仅当源字符串的长度(不包含
\0)小于指定的复制长度n时,才会额外补\0填满n个长度 - 如果源字符串长度 >=n,仅复制前n个字符,不会追加
\0
你的代码中执行strncpy(name5, name1, 3)时,源字符串name1是apple,长度5大于3,因此仅复制a/p/p三个字符到name5,没有补充\0。而name5是栈上的局部未初始化数组,剩余空间都是随机的垃圾值,printf用%s输出时会持续读取直到遇到\0,因此后面的随机内存内容就表现为乱码。
2. strncat拼接后name4偶发乱码的原因
这个问题本质和上一个问题同源,分两种情况:
- 首先执行
strncpy(name4, name3,5)时,源字符串elefant长度7大于5,同样不会给name4追加\0。你本次测试输出name4为elefa只是巧合,刚好name4第6个字节的随机值是\0;如果这个位置是其他非0值,name4本身输出就会带乱码 strncat的执行前提是目标字符串必须是合法的、以\0结尾的C字符串,它会从目标的\0位置开始追加内容。如果name4本身没有\0,strncat会先向后越界查找\0,要么触发内存访问错误,要么追加的位置异常,最终输出就会带乱码。
修复建议
- 所有
strncpy调用后手动追加结束符,例如:
strncpy(name5, name1, 3); name5[3] = '\0'; // 手动补结束符 strncpy(name4, name3,5); name4[5] = '\0';
- 初始化字符数组时主动清零,避免随机垃圾值影响:
char name5[30] = {0}; - 使用
strncat前确保目标字符串已正确以\0结尾,且目标缓冲区有足够的剩余空间容纳追加的内容和结束符。
内容的提问来源于stack exchange,提问作者Dalton Cézane
相关产品推荐
相关产品推荐

