C语言数组复制后打印出现重复内容的原因咨询
为什么复制字符数组后打印第二个数组会出现重复内容?
这是一个很典型的C语言字符串新手坑——你忘记给字符数组添加字符串终止符'\0'了!让我给你拆解一下问题原因和解决办法:
问题重现
先看看你的代码和运行结果:
#include <stdio.h> int main() { char test1[4]; char test2[4]; test1[0] = 't'; test1[1] = 'e'; test1[2] = 's'; test1[3] = 't'; /* Copy the stuff from test1 into test2 */ for(int j = 0; j<4; j++){ test2[j] = test1[j]; } printf("test1: %s\n", test1); printf("test2: %s\n", test2); printf("end testing"); return 0; }
运行结果:
test1: test test2: testtest end testing
问题根源
在C语言里,printf用%s输出字符串时,会从指定内存地址开始逐个读取字符,直到遇到'\0'(空字符,ASCII值为0)才会停止。但你定义的test1和test2都是长度为4的char数组,刚好只能放下t、e、s、t这4个字符,完全没有多余的空间存放'\0'——这就导致这两个数组都不是合法的C字符串。
而在栈内存中,局部变量(比如这里的test1和test2)通常是连续分配的。当你打印test2时,printf读完test2的4个字符后,会继续读取相邻的内存区域(刚好就是test1的内容),直到在某个位置碰巧遇到'\0',所以就输出了testtest。至于test1打印正常,只是因为test1后面的内存刚好有一个'\0'(可能是栈上的其他数据或者栈帧的结束标志),纯属运气好而已。
解决办法
有几种简单的方式可以修复这个问题:
方法1:手动添加终止符,扩大数组长度
把数组长度定义为5,预留出存放'\0'的位置,然后手动添加终止符:
#include <stdio.h> int main() { char test1[5]; char test2[5]; test1[0] = 't'; test1[1] = 'e'; test1[2] = 's'; test1[3] = 't'; test1[4] = '\0'; // 必须添加的字符串终止符 /* 复制包括终止符在内的所有内容 */ for(int j = 0; j<5; j++){ test2[j] = test1[j]; } printf("test1: %s\n", test1); printf("test2: %s\n", test2); printf("end testing"); return 0; }
方法2:用标准库函数strcpy自动处理终止符
使用<string.h>里的strcpy函数,它会自动把源字符串的'\0'也复制过去,但要确保目标数组长度足够:
#include <stdio.h> #include <string.h> int main() { // 用字符串字面量初始化,编译器会自动添加'\0',数组长度自动为5 char test1[] = "test"; char test2[5]; strcpy(test2, test1); // 自动复制所有字符包括'\0' printf("test1: %s\n", test1); printf("test2: %s\n", test2); printf("end testing"); return 0; }
方法3:更安全的初始化方式
直接用char test1[] = "test";初始化数组,编译器会自动计算出需要的长度(4个字符+1个终止符,共5位),避免手动计算长度出错。
内容的提问来源于stack exchange,提问作者jabe
相关产品推荐
相关产品推荐

