我的程序是这样的。
int main(int argc, char **argv)
{
char str1[5],str2[4];
scanf("%s%s",str1,str2);
printf("%s\n",str1);
printf("%s\n",str2);
return 0;
},如果str1对应的输入字符串是5个的话就会出错,比如我输入abcde回车abcd回车,打印出来的是abcdeabcd,abcd.。如果我第一个字符串输入的字符个数少于5个的话就不会有问题,请问这是为什么?
你申请数组空间后,内存中存放字符的顺序是:
str1[0],str1[1],str1[2],str1[3],str1[4],str2[0],str2[1],str2[2],str2[3]
当输入字符串是:abc 123时,存储的数据str1[0]~str1[4],str2[0]~str2[3]为:
‘a','b','c',0,xx,'1','2','3',0
其中,xx表示一个不关心的任意值,也就是说输入字符串"abc"需要占用4个字节的存储空间
当输入字符串1为"abcde"时,存储的数据为:'a','b','c','d','e',0,xx,xx,xx
字符串末尾的0已经超出了str1开设的存储空间而存放到了str2[0]位置
接着再输入字符串"1234"时,str2[0]的str1字串的结尾符被字符'1'覆盖,
存储的数据为:'a','b','c','d','e',’1‘,’2‘,’3‘,’4‘,0
而且由于str2输入字符数为4个其占用空间也超出了str2的空间范围,那么上边存储的0值也不知道覆盖了什么变量的位置,导致其他变量的值被冲掉了。
当执行printf("%s\n",str1);时,printf从str1[0]开始输出的字符串(遇0结束输出)为abcde1234
当执行printf("%s\n",str2);时,printf从str2[0]开始输出的字符串(遇0结束输出)为1234
所以你输入的第1个字符串字符数少于5时,存储不会溢出,多于4个时,末尾的0就会被输入的str2所覆盖而失效,且多于5的字符也会被覆盖。scanf并不能保证输入字符的长短不会溢出,你应当在设计程序时考虑到这点,预先定义足够的字符串保存空间或用其他方法来避免这个问题的出现。
为什么str1过界的字符就一定要到str2里面呢,我看了这2个数组的地址,是连在一起的,是不是栈在分配数据的时候就默认字符数组分一起,然后整数数组分一起?
追答可以说由于你开设两个空间的定义语句的编译结果导致的,编译程序自动把你这两个空间紧接着开辟了,这是与你的变量定义语句以及编译程序相关的。但你在程序中不能假设这个是一定的,只能说碰巧了。
那是不是说每种类型的数据在栈中分配的时候都是分在连续的地址中的?
追答应该是这样的,不过也要看编辑器,还有对齐方式等因素
其实像这种问题,一般来说没必要搞的太清晰,知道个大概即可
字符数组怎么避免不初始化?
1. 静态初始化:在定义字符数组时,可以直接给定初始值,这样数组在创建时就会被初始化为指定的值。例如:```c char str[100] = "Hello, World!";```2. 动态初始化:在需要使用字符数组之前,可以通过字符串赋值函数(如`strcpy`或`sprintf`)将一个字符串赋值给数组,确保数组中有合适的初始值。
C语言字符数组如何初始化?
C语言允许用字符串的方式对数组作初始化赋值。例如:staticcharc[]={'c','','p','r','o','g','r','a','m'};可写为:staticcharc[]={"Cprogram"};或去掉{}写为:staticcharc[]="Cprogram";当对全体元素赋初值时也可以省去长度说明。例如:staticcharc[]={`c`,``,`p`,`r`...
C语言数组字符串初始化问题
当输入字符串是:abc 123时,存储的数据str1[0]~str1[4],str2[0]~str2[3]为:‘a','b','c',0,xx,'1','2','3',0 其中,xx表示一个不关心的任意值,也就是说输入字符串"abc"需要占用4个字节的存储空间 当输入字符串1为"abcde"时,存储的数据为:'a','b','c','d','e',...
C语言的问题,字符串数组初始化 a[30]={\\0}、a[30]={0}、a[30]={"0...
int i;for(i=0;i<100;i++){ printf("%d \\n",a[i]);}
C语言初始化字符型数组时,两种方式的区别?
而b的初始化使b成为一个“字符数组”,它的最后没有字符串结束符,系统也不会主动加上。所以,当后面你用字符串操作函数strlen和字符串格式符%s输出b时,系统会一直往后找,直到找到一个'\\0'时,系统便认为,这就是字符串结束的地方,故,输出的字符串长度和字符串本身都是错误的。b除了所以与a...
C语言字符串问题
1. 字符串初始化,如果逐个赋值的话,系统不一定会自动添加'\\0',除非指定了长度且指定的长度大于等于你赋值的字符的个数加1,即最小为你赋值的字符个数加1。假设你指定的字符个数为n,长度为len,则系统会将剩下的(len-n)个元素都赋值为'\\0',当n等于len时,不会添加任何'\\0'。之所以出现...
C语言定义字符型数组时,两种初始化方式的区别?
这二种初始化方式的区别在于第一种方法是存储了5个字节的内容,即能看到的个字母,外加一个字符串结束符'\\0'。这样才能正确地以%s的形式来输出这个字符串;而第二种方法则是只存储了4个字母,但是却没有字符串结束符,所以它不能以%s的形式正确输出。如果也要以%s的形式输出这个字符串,那就应该...
c语言字符串对字符数组初始化
不可以,array bound overflow,数组越界,还要存一个'\\0'.其实碰到这种问题,你应该自己去开发环境中试一下,看看报不报错。
字符串数组的初始化方式?
在c语言中,将字符串作为字符数组来处理。因此可以使用字符串来初始化字符数组。1 char str[]={"I am happy"};也可以省略花括号。1 char str[]="I am happy";但是,上述这种字符数组的整体赋值只能在字符数组初始化时使用,不能用于字符数组的赋值,字符数组的赋值只能对其元素一一赋值,下面的...
c语言数组的初始化表示方法
char str[] = "Hello"; \/\/字符数组初始化为字符串"Hello"注意,字符数组的末尾会自动添加一个空字符`\\0`作为字符串的结束标志。五、动态初始化 除了声明时的静态初始化,也可以在程序运行时动态地初始化数组元素。这通常在循环结构中进行。例如:c int array[5];for { array[i] = i * 2; ...